blob: 6d78c5697f8b9604acb2e8a477e401aa4b658b44 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "p2p/base/packettransportinternal.h"
30#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080031#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
33namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000034using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080035using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000036
deadbeef2d110be2016-01-13 12:00:26 -080037namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020038
39struct SendPacketMessageData : public rtc::MessageData {
40 rtc::CopyOnWriteBuffer packet;
41 rtc::PacketOptions options;
42};
43
deadbeef2d110be2016-01-13 12:00:26 -080044} // namespace
45
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046enum {
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000047 MSG_EARLYMEDIATIMEOUT = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020048 MSG_SEND_RTP_PACKET,
49 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053};
54
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000055static void SafeSetError(const std::string& message, std::string* error_desc) {
56 if (error_desc) {
57 *error_desc = message;
58 }
59}
60
jbaucheec21bd2016-03-20 06:15:43 -070061static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070063 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064}
65
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070066template <class Codec>
67void RtpParametersFromMediaDescription(
68 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070069 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070070 RtpParameters<Codec>* params) {
71 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080072 // a description without codecs. Currently the ORTC implementation is relying
73 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070074 if (desc->has_codecs()) {
75 params->codecs = desc->codecs();
76 }
77 // TODO(pthatcher): See if we really need
78 // rtp_header_extensions_set() and remove it if we don't.
79 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070080 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070081 }
deadbeef13871492015-12-09 12:37:51 -080082 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070083}
84
nisse05103312016-03-16 02:22:50 -070085template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070086void RtpSendParametersFromMediaDescription(
87 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070088 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070089 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070090 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070091 send_params->max_bandwidth_bps = desc->bandwidth();
92}
93
Danil Chapovalov33b01f22016-05-11 19:55:27 +020094BaseChannel::BaseChannel(rtc::Thread* worker_thread,
95 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -080096 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -080097 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -070098 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -080099 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800100 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200101 : worker_thread_(worker_thread),
102 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800103 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104 content_name_(content_name),
zstein56162b92017-04-24 16:54:35 -0700105 rtcp_mux_required_(rtcp_mux_required),
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800106 unencrypted_rtp_transport_(
107 rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required)),
deadbeef7af91dd2016-12-13 11:29:11 -0800108 srtp_required_(srtp_required),
Zhi Huang1d88d742017-11-15 15:58:49 -0800109 media_channel_(std::move(media_channel)) {
Steve Anton8699a322017-11-06 15:53:33 -0800110 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800111 rtp_transport_ = unencrypted_rtp_transport_.get();
112 ConnectToRtpTransport();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100113 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114}
115
116BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800117 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800118 RTC_DCHECK_RUN_ON(worker_thread_);
wu@webrtc.org78187522013-10-07 23:32:02 +0000119 Deinit();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200120 // Eats any outstanding messages or packets.
121 worker_thread_->Clear(&invoker_);
122 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123 // We must destroy the media channel before the transport channel, otherwise
124 // the media channel may try to send on the dead transport channel. NULLing
125 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800126 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100127 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200128}
129
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800130void BaseChannel::ConnectToRtpTransport() {
131 RTC_DCHECK(rtp_transport_);
132 rtp_transport_->SignalReadyToSend.connect(
133 this, &BaseChannel::OnTransportReadyToSend);
134 // TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
135 // with a callback interface later so that the demuxer can select which
136 // channel to signal.
137 rtp_transport_->SignalPacketReceived.connect(this,
138 &BaseChannel::OnPacketReceived);
139 rtp_transport_->SignalNetworkRouteChanged.connect(
140 this, &BaseChannel::OnNetworkRouteChanged);
141 rtp_transport_->SignalWritableState.connect(this,
142 &BaseChannel::OnWritableState);
143 rtp_transport_->SignalSentPacket.connect(this,
144 &BaseChannel::SignalSentPacket_n);
145}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200146
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800147void BaseChannel::DisconnectFromRtpTransport() {
148 RTC_DCHECK(rtp_transport_);
149 rtp_transport_->SignalReadyToSend.disconnect(this);
150 rtp_transport_->SignalPacketReceived.disconnect(this);
151 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
152 rtp_transport_->SignalWritableState.disconnect(this);
153 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200154}
155
Steve Anton8699a322017-11-06 15:53:33 -0800156void BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
deadbeeff5346592017-01-24 21:51:21 -0800157 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800158 rtc::PacketTransportInternal* rtp_packet_transport,
159 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -0800160 RTC_DCHECK_RUN_ON(worker_thread_);
161 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800162 SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport,
163 rtp_packet_transport, rtcp_packet_transport);
164
165 if (rtcp_mux_required_) {
166 rtcp_mux_filter_.SetActive();
167 }
Steve Anton8699a322017-11-06 15:53:33 -0800168 });
169
deadbeeff5346592017-01-24 21:51:21 -0800170 // Both RTP and RTCP channels should be set, we can call SetInterface on
171 // the media channel and it can set network options.
wu@webrtc.orgde305012013-10-31 15:40:38 +0000172 media_channel_->SetInterface(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173}
174
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800175void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
176 RTC_DCHECK_RUN_ON(worker_thread_);
177 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
178 SetRtpTransport(rtp_transport);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200179
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800180 if (rtcp_mux_required_) {
181 rtcp_mux_filter_.SetActive();
182 }
183 });
184
185 // Both RTP and RTCP channels should be set, we can call SetInterface on
186 // the media channel and it can set network options.
187 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200188}
189
wu@webrtc.org78187522013-10-07 23:32:02 +0000190void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200191 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000192 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200193 // Packets arrive on the network thread, processing packets calls virtual
194 // functions, so need to stop this process in Deinit that is called in
195 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800196 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
197 FlushRtcpMessages_n();
198
199 if (dtls_srtp_transport_) {
200 dtls_srtp_transport_->SetDtlsTransports(nullptr, nullptr);
201 } else {
202 rtp_transport_->SetRtpPacketTransport(nullptr);
203 rtp_transport_->SetRtcpPacketTransport(nullptr);
204 }
205 // Clear pending read packets/messages.
206 network_thread_->Clear(&invoker_);
207 network_thread_->Clear(this);
208 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000209}
210
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800211void BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
212 if (!network_thread_->IsCurrent()) {
213 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
214 SetRtpTransport(rtp_transport);
215 return;
216 });
217 }
218
219 RTC_DCHECK(rtp_transport);
220
221 if (rtp_transport_) {
222 DisconnectFromRtpTransport();
223 }
224 rtp_transport_ = rtp_transport;
225 RTC_LOG(LS_INFO) << "Setting the RtpTransport for " << content_name();
226 ConnectToRtpTransport();
227
228 UpdateWritableState_n();
229}
230
zhihuangb2cdd932017-01-19 16:54:25 -0800231void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
232 DtlsTransportInternal* rtcp_dtls_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800233 network_thread_->Invoke<void>(
234 RTC_FROM_HERE,
235 Bind(&BaseChannel::SetTransports_n, this, rtp_dtls_transport,
236 rtcp_dtls_transport, rtp_dtls_transport, rtcp_dtls_transport));
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000237}
238
deadbeeff5346592017-01-24 21:51:21 -0800239void BaseChannel::SetTransports(
deadbeef5bd5ca32017-02-10 11:31:50 -0800240 rtc::PacketTransportInternal* rtp_packet_transport,
241 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800242 network_thread_->Invoke<void>(
243 RTC_FROM_HERE, Bind(&BaseChannel::SetTransports_n, this, nullptr, nullptr,
244 rtp_packet_transport, rtcp_packet_transport));
245}
zhihuangf5b251b2017-01-12 19:37:48 -0800246
deadbeeff5346592017-01-24 21:51:21 -0800247void BaseChannel::SetTransports_n(
248 DtlsTransportInternal* rtp_dtls_transport,
249 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800250 rtc::PacketTransportInternal* rtp_packet_transport,
251 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800252 RTC_DCHECK(network_thread_->IsCurrent());
253 // Validate some assertions about the input.
254 RTC_DCHECK(rtp_packet_transport);
255 RTC_DCHECK_EQ(NeedsRtcpTransport(), rtcp_packet_transport != nullptr);
256 if (rtp_dtls_transport || rtcp_dtls_transport) {
257 // DTLS/non-DTLS pointers should be to the same object.
258 RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport);
259 RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport);
260 // Can't go from non-DTLS to DTLS.
zsteine8ab5432017-07-12 11:48:11 -0700261 RTC_DCHECK(!rtp_transport_->rtp_packet_transport() || rtp_dtls_transport_);
deadbeeff5346592017-01-24 21:51:21 -0800262 } else {
263 // Can't go from DTLS to non-DTLS.
264 RTC_DCHECK(!rtp_dtls_transport_);
265 }
266 // Transport names should be the same.
zhihuangb2cdd932017-01-19 16:54:25 -0800267 if (rtp_dtls_transport && rtcp_dtls_transport) {
268 RTC_DCHECK(rtp_dtls_transport->transport_name() ==
269 rtcp_dtls_transport->transport_name());
zhihuangb2cdd932017-01-19 16:54:25 -0800270 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800271
272 if (rtp_packet_transport == rtp_transport_->rtp_packet_transport()) {
273 // Nothing to do if transport isn't changing.
274 return;
275 }
276
deadbeeff5346592017-01-24 21:51:21 -0800277 std::string debug_name;
278 if (rtp_dtls_transport) {
279 transport_name_ = rtp_dtls_transport->transport_name();
280 debug_name = transport_name_;
281 } else {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800282 debug_name = rtp_packet_transport->transport_name();
deadbeeff5346592017-01-24 21:51:21 -0800283 }
deadbeefac22f702017-01-12 21:59:29 -0800284 // If this BaseChannel doesn't require RTCP mux and we haven't fully
285 // negotiated RTCP mux, we need an RTCP transport.
deadbeeff5346592017-01-24 21:51:21 -0800286 if (rtcp_packet_transport) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100287 RTC_LOG(LS_INFO) << "Setting RTCP Transport for " << content_name()
288 << " on " << debug_name << " transport "
289 << rtcp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800290 SetTransport_n(/*rtcp=*/true, rtcp_dtls_transport, rtcp_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000291 }
292
Mirko Bonadei675513b2017-11-09 11:09:25 +0100293 RTC_LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on "
294 << debug_name << " transport " << rtp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800295 SetTransport_n(/*rtcp=*/false, rtp_dtls_transport, rtp_packet_transport);
296
297 // Set DtlsTransport/PacketTransport for RTP-level transport.
298 if ((rtp_dtls_transport_ || rtcp_dtls_transport_) && dtls_srtp_transport_) {
299 // When setting the transport with non-null |dtls_srtp_transport_|, we are
300 // using DTLS-SRTP. This could happen for bundling. If the
301 // |dtls_srtp_transport| is null, we cannot tell if it doing DTLS-SRTP or
302 // SDES until the description is set. So don't call |EnableDtlsSrtp_n| here.
303 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport,
304 rtcp_dtls_transport);
305 } else {
306 rtp_transport_->SetRtpPacketTransport(rtp_packet_transport);
307 rtp_transport_->SetRtcpPacketTransport(rtcp_packet_transport);
308 }
guoweis46383312015-12-17 16:45:59 -0800309
deadbeefcbecd352015-09-23 11:50:27 -0700310 // Update aggregate writable/ready-to-send state between RTP and RTCP upon
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700311 // setting new transport channels.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200312 UpdateWritableState_n();
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000313}
314
deadbeeff5346592017-01-24 21:51:21 -0800315void BaseChannel::SetTransport_n(
316 bool rtcp,
317 DtlsTransportInternal* new_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800318 rtc::PacketTransportInternal* new_packet_transport) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200319 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800320 if (new_dtls_transport) {
321 RTC_DCHECK(new_dtls_transport == new_packet_transport);
322 }
deadbeeff5346592017-01-24 21:51:21 -0800323 DtlsTransportInternal*& old_dtls_transport =
zhihuangb2cdd932017-01-19 16:54:25 -0800324 rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
zsteind48dbda2017-04-04 19:45:57 -0700325 rtc::PacketTransportInternal* old_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700326 rtcp ? rtp_transport_->rtcp_packet_transport()
327 : rtp_transport_->rtp_packet_transport();
zhihuangb2cdd932017-01-19 16:54:25 -0800328
deadbeeff5346592017-01-24 21:51:21 -0800329 if (!old_packet_transport && !new_packet_transport) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700330 // Nothing to do.
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000331 return;
332 }
zhihuangb2cdd932017-01-19 16:54:25 -0800333
deadbeeff5346592017-01-24 21:51:21 -0800334 RTC_DCHECK(old_packet_transport != new_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000335
deadbeeff5346592017-01-24 21:51:21 -0800336 old_dtls_transport = new_dtls_transport;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000337
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800338 // If there's no new transport, we're done.
deadbeeff5346592017-01-24 21:51:21 -0800339 if (!new_packet_transport) {
340 return;
341 }
342
343 if (rtcp && new_dtls_transport) {
Zhi Huangcf990f52017-09-22 12:12:30 -0700344 RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_active()))
345 << "Setting RTCP for DTLS/SRTP after the DTLS is active "
deadbeeff5346592017-01-24 21:51:21 -0800346 << "should never happen.";
347 }
zstein56162b92017-04-24 16:54:35 -0700348
deadbeeff5346592017-01-24 21:51:21 -0800349 auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
350 for (const auto& pair : socket_options) {
351 new_packet_transport->SetOption(pair.first, pair.second);
guoweis46383312015-12-17 16:45:59 -0800352 }
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000353}
354
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000355bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700356 worker_thread_->Invoke<void>(
357 RTC_FROM_HERE,
358 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
359 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360 return true;
361}
362
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363bool BaseChannel::AddRecvStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700364 return InvokeOnWorker<bool>(RTC_FROM_HERE,
365 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366}
367
Peter Boström0c4e06b2015-10-07 12:23:21 +0200368bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700369 return InvokeOnWorker<bool>(
370 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371}
372
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000373bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700374 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700375 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000376}
377
Peter Boström0c4e06b2015-10-07 12:23:21 +0200378bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700379 return InvokeOnWorker<bool>(
380 RTC_FROM_HERE,
381 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000382}
383
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800385 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000386 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100387 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700388 return InvokeOnWorker<bool>(
389 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800390 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000391}
392
393bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800394 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000395 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100396 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700397 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800398 RTC_FROM_HERE,
399 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400}
401
zhihuangf5b251b2017-01-12 19:37:48 -0800402bool BaseChannel::NeedsRtcpTransport() {
deadbeefac22f702017-01-12 21:59:29 -0800403 // If this BaseChannel doesn't require RTCP mux and we haven't fully
404 // negotiated RTCP mux, we need an RTCP transport.
zstein56162b92017-04-24 16:54:35 -0700405 return !rtcp_mux_required_ && !rtcp_mux_filter_.IsFullyActive();
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +0000406}
407
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700408bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000409 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800410 return enabled() &&
411 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412}
413
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700414bool BaseChannel::IsReadyToSendMedia_w() const {
415 // Need to access some state updated on the network thread.
416 return network_thread_->Invoke<bool>(
417 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
418}
419
420bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421 // Send outgoing data if we are enabled, have local and remote content,
422 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800423 return enabled() &&
424 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
425 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huangcf990f52017-09-22 12:12:30 -0700426 was_ever_writable() && (srtp_active() || !ShouldSetupDtlsSrtp_n());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000427}
428
jbaucheec21bd2016-03-20 06:15:43 -0700429bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700430 const rtc::PacketOptions& options) {
431 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000432}
433
jbaucheec21bd2016-03-20 06:15:43 -0700434bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700435 const rtc::PacketOptions& options) {
436 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437}
438
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000439int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200441 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700442 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200443}
444
445int BaseChannel::SetOption_n(SocketType type,
446 rtc::Socket::Option opt,
447 int value) {
448 RTC_DCHECK(network_thread_->IsCurrent());
deadbeef5bd5ca32017-02-10 11:31:50 -0800449 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000451 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700452 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700453 socket_options_.push_back(
454 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000455 break;
456 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700457 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700458 rtcp_socket_options_.push_back(
459 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000460 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000461 }
deadbeeff5346592017-01-24 21:51:21 -0800462 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463}
464
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800465void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200466 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800467 if (writable) {
468 // This is used to cover the scenario when the DTLS handshake is completed
469 // and DtlsTransport becomes writable before the remote description is set.
470 if (ShouldSetupDtlsSrtp_n()) {
471 EnableDtlsSrtp_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700472 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800473 ChannelWritable_n();
474 } else {
475 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800476 }
477}
478
Zhi Huang942bc2e2017-11-13 13:26:07 -0800479void BaseChannel::OnNetworkRouteChanged(
480 rtc::Optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200481 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800482 rtc::NetworkRoute new_route;
483 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800484 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000485 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800486 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
487 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
488 // work correctly. Intentionally leave it broken to simplify the code and
489 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800490 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800491 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800492 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700493}
494
zstein56162b92017-04-24 16:54:35 -0700495void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800496 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
497 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000498}
499
stefanc1aeaf02015-10-15 07:26:07 -0700500bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700501 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700502 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200503 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
504 // If the thread is not our network thread, we will post to our network
505 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506 // synchronize access to all the pieces of the send path, including
507 // SRTP and the inner workings of the transport channels.
508 // The only downside is that we can't return a proper failure code if
509 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200510 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000511 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200512 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
513 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800514 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700515 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700516 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000517 return true;
518 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200519 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520
521 // Now that we are on the correct thread, ensure we have a place to send this
522 // packet before doing anything. (We might get RTCP packets that we don't
523 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
524 // transport.
zsteine8ab5432017-07-12 11:48:11 -0700525 if (!rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 return false;
527 }
528
529 // Protect ourselves against crazy data.
530 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100531 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
532 << RtpRtcpStringLiteral(rtcp)
533 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 return false;
535 }
536
Zhi Huangcf990f52017-09-22 12:12:30 -0700537 if (!srtp_active()) {
538 if (srtp_required_) {
539 // The audio/video engines may attempt to send RTCP packets as soon as the
540 // streams are created, so don't treat this as an error for RTCP.
541 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
542 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000543 return false;
544 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700545 // However, there shouldn't be any RTP packets sent before SRTP is set up
546 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100547 RTC_LOG(LS_ERROR)
548 << "Can't send outgoing RTP packet when SRTP is inactive"
549 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700550 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800551 return false;
552 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800553
554 std::string packet_type = rtcp ? "RTCP" : "RTP";
555 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
556 << " packet without encryption.";
557 } else {
558 // Make sure we didn't accidentally send any packets without encryption.
559 RTC_DCHECK(rtp_transport_ == sdes_transport_.get() ||
560 rtp_transport_ == dtls_srtp_transport_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800563 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
564 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565}
566
zstein3dcf0e92017-06-01 13:22:42 -0700567bool BaseChannel::HandlesPayloadType(int packet_type) const {
zsteine8ab5432017-07-12 11:48:11 -0700568 return rtp_transport_->HandlesPayloadType(packet_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569}
570
zstein3dcf0e92017-06-01 13:22:42 -0700571void BaseChannel::OnPacketReceived(bool rtcp,
zstein634977b2017-07-14 12:30:04 -0700572 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -0700573 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000574 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700576 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 }
578
Zhi Huangcf990f52017-09-22 12:12:30 -0700579 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580 // Our session description indicates that SRTP is required, but we got a
581 // packet before our SRTP filter is active. This means either that
582 // a) we got SRTP packets before we received the SDES keys, in which case
583 // we can't decrypt it anyway, or
584 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800585 // transports, so we haven't yet extracted keys, even if DTLS did
586 // complete on the transport that the packets are being sent on. It's
587 // really good practice to wait for both RTP and RTCP to be good to go
588 // before sending media, to prevent weird failure modes, so it's fine
589 // for us to just eat packets here. This is all sidestepped if RTCP mux
590 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100591 RTC_LOG(LS_WARNING)
592 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
593 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 return;
595 }
596
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200597 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700598 RTC_FROM_HERE, worker_thread_,
zstein634977b2017-07-14 12:30:04 -0700599 Bind(&BaseChannel::ProcessPacket, this, rtcp, *packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200600}
601
zstein3dcf0e92017-06-01 13:22:42 -0700602void BaseChannel::ProcessPacket(bool rtcp,
603 const rtc::CopyOnWriteBuffer& packet,
604 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200605 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700606
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200607 // Need to copy variable because OnRtcpReceived/OnPacketReceived
608 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
609 rtc::CopyOnWriteBuffer data(packet);
610 if (rtcp) {
611 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000612 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200613 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614 }
615}
616
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700618 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619 if (enabled_)
620 return;
621
Mirko Bonadei675513b2017-11-09 11:09:25 +0100622 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700624 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000625}
626
627void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700628 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 if (!enabled_)
630 return;
631
Mirko Bonadei675513b2017-11-09 11:09:25 +0100632 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700634 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635}
636
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200637void BaseChannel::UpdateWritableState_n() {
zsteind48dbda2017-04-04 19:45:57 -0700638 rtc::PacketTransportInternal* rtp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700639 rtp_transport_->rtp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700640 rtc::PacketTransportInternal* rtcp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700641 rtp_transport_->rtcp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700642 if (rtp_packet_transport && rtp_packet_transport->writable() &&
643 (!rtcp_packet_transport || rtcp_packet_transport->writable())) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200644 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700645 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200646 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700647 }
648}
649
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200650void BaseChannel::ChannelWritable_n() {
651 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800652 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800654 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655
Mirko Bonadei675513b2017-11-09 11:09:25 +0100656 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
657 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000659 was_ever_writable_ = true;
660 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700661 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662}
663
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200664bool BaseChannel::ShouldSetupDtlsSrtp_n() const {
zhihuangb2cdd932017-01-19 16:54:25 -0800665 // Since DTLS is applied to all transports, checking RTP should be enough.
666 return rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667}
668
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200669void BaseChannel::ChannelNotWritable_n() {
670 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 if (!writable_)
672 return;
673
Mirko Bonadei675513b2017-11-09 11:09:25 +0100674 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700676 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000677}
678
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200679bool BaseChannel::SetRtpTransportParameters(
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700680 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800681 SdpType type,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700682 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700683 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700684 std::string* error_desc) {
jbauch5869f502017-06-29 12:31:36 -0700685 std::vector<int> encrypted_extension_ids;
686 for (const webrtc::RtpExtension& extension : extensions) {
687 if (extension.encrypt) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100688 RTC_LOG(LS_INFO) << "Using " << (src == CS_LOCAL ? "local" : "remote")
689 << " encrypted extension: " << extension.ToString();
jbauch5869f502017-06-29 12:31:36 -0700690 encrypted_extension_ids.push_back(extension.id);
691 }
692 }
693
deadbeef7af91dd2016-12-13 11:29:11 -0800694 // Cache srtp_required_ for belt and suspenders check on SendPacket
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200695 return network_thread_->Invoke<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800696 RTC_FROM_HERE,
697 Bind(&BaseChannel::SetRtpTransportParameters_n, this, content, type, src,
698 encrypted_extension_ids, error_desc));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200699}
700
701bool BaseChannel::SetRtpTransportParameters_n(
702 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800703 SdpType type,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200704 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700705 const std::vector<int>& encrypted_extension_ids,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200706 std::string* error_desc) {
707 RTC_DCHECK(network_thread_->IsCurrent());
708
Steve Anton3828c062017-12-06 10:34:51 -0800709 if (!SetSrtp_n(content->cryptos(), type, src, encrypted_extension_ids,
710 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700711 return false;
712 }
713
Steve Anton3828c062017-12-06 10:34:51 -0800714 if (!SetRtcpMux_n(content->rtcp_mux(), type, src, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700715 return false;
716 }
717
718 return true;
719}
720
zhihuangb2cdd932017-01-19 16:54:25 -0800721// |dtls| will be set to true if DTLS is active for transport and crypto is
722// empty.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200723bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
724 bool* dtls,
725 std::string* error_desc) {
deadbeeff5346592017-01-24 21:51:21 -0800726 *dtls = rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000727 if (*dtls && !cryptos.empty()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200728 SafeSetError("Cryptos must be empty when DTLS is active.", error_desc);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000729 return false;
730 }
731 return true;
732}
733
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800734void BaseChannel::EnableSdes_n() {
735 if (sdes_transport_) {
736 return;
Zhi Huangcf990f52017-09-22 12:12:30 -0700737 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800738 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
739 // time.
740 RTC_DCHECK(!dtls_srtp_transport_);
741 RTC_DCHECK(unencrypted_rtp_transport_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800742 sdes_transport_ = rtc::MakeUnique<webrtc::SrtpTransport>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800743 std::move(unencrypted_rtp_transport_));
Zhi Huangd7455782017-11-30 14:50:52 -0800744#if defined(ENABLE_EXTERNAL_AUTH)
745 sdes_transport_->EnableExternalAuth();
746#endif
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800747 SetRtpTransport(sdes_transport_.get());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800748 RTC_LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
749}
750
751void BaseChannel::EnableDtlsSrtp_n() {
752 if (dtls_srtp_transport_) {
753 return;
754 }
755 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
756 // time.
757 RTC_DCHECK(!sdes_transport_);
758 RTC_DCHECK(unencrypted_rtp_transport_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800759
760 auto srtp_transport = rtc::MakeUnique<webrtc::SrtpTransport>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800761 std::move(unencrypted_rtp_transport_));
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800762#if defined(ENABLE_EXTERNAL_AUTH)
763 srtp_transport->EnableExternalAuth();
764#endif
765 dtls_srtp_transport_ =
766 rtc::MakeUnique<webrtc::DtlsSrtpTransport>(std::move(srtp_transport));
767
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800768 SetRtpTransport(dtls_srtp_transport_.get());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800769 if (cached_send_extension_ids_) {
770 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
771 *cached_send_extension_ids_);
772 }
773 if (cached_recv_extension_ids_) {
774 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
775 *cached_recv_extension_ids_);
776 }
777 // Set the DtlsTransport and the |dtls_srtp_transport_| will handle the DTLS
778 // relate signal internally.
779 RTC_DCHECK(rtp_dtls_transport_);
780 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
781 rtcp_dtls_transport_);
782
783 RTC_LOG(LS_INFO) << "Wrapping SrtpTransport in DtlsSrtpTransport.";
Zhi Huangcf990f52017-09-22 12:12:30 -0700784}
785
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200786bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
Steve Anton3828c062017-12-06 10:34:51 -0800787 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000788 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700789 const std::vector<int>& encrypted_extension_ids,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000790 std::string* error_desc) {
Peter Boströmca8b4042016-03-08 14:24:13 -0800791 TRACE_EVENT0("webrtc", "BaseChannel::SetSrtp_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792 bool ret = false;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000793 bool dtls = false;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200794 ret = CheckSrtpConfig_n(cryptos, &dtls, error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000795 if (!ret) {
796 return false;
797 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700798
799 // If SRTP was not required, but we're setting a description that uses SDES,
800 // we need to upgrade to an SrtpTransport.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800801 if (!sdes_transport_ && !dtls && !cryptos.empty()) {
802 EnableSdes_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700803 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800804
Steve Anton3828c062017-12-06 10:34:51 -0800805 if ((type == SdpType::kAnswer || type == SdpType::kPrAnswer) && dtls) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800806 EnableDtlsSrtp_n();
807 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800808
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800809 UpdateEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
810
811 if (!dtls) {
Steve Anton3828c062017-12-06 10:34:51 -0800812 switch (type) {
813 case SdpType::kOffer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700814 ret = sdes_negotiator_.SetOffer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800815 break;
Steve Anton3828c062017-12-06 10:34:51 -0800816 case SdpType::kPrAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700817 ret = sdes_negotiator_.SetProvisionalAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800818 break;
Steve Anton3828c062017-12-06 10:34:51 -0800819 case SdpType::kAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700820 ret = sdes_negotiator_.SetAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800821 break;
822 default:
823 break;
824 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700825
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800826 // If setting an SDES answer succeeded, apply the negotiated parameters
827 // to the SRTP transport.
Steve Anton3828c062017-12-06 10:34:51 -0800828 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800829 if (sdes_negotiator_.send_cipher_suite() &&
830 sdes_negotiator_.recv_cipher_suite()) {
831 RTC_DCHECK(cached_send_extension_ids_);
832 RTC_DCHECK(cached_recv_extension_ids_);
833 ret = sdes_transport_->SetRtpParams(
834 *(sdes_negotiator_.send_cipher_suite()),
835 sdes_negotiator_.send_key().data(),
836 static_cast<int>(sdes_negotiator_.send_key().size()),
837 *(cached_send_extension_ids_),
838 *(sdes_negotiator_.recv_cipher_suite()),
839 sdes_negotiator_.recv_key().data(),
840 static_cast<int>(sdes_negotiator_.recv_key().size()),
841 *(cached_recv_extension_ids_));
842 } else {
843 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
Steve Anton3828c062017-12-06 10:34:51 -0800844 if (type == SdpType::kAnswer && sdes_transport_) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800845 // Explicitly reset the |sdes_transport_| if no crypto param is
846 // provided in the answer. No need to call |ResetParams()| for
847 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
848 sdes_transport_->ResetParams();
849 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700850 }
851 }
852 }
853
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000854 if (!ret) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800855 SafeSetError("Failed to setup SRTP.", error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000856 return false;
857 }
858 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859}
860
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200861bool BaseChannel::SetRtcpMux_n(bool enable,
Steve Anton3828c062017-12-06 10:34:51 -0800862 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000863 ContentSource src,
864 std::string* error_desc) {
deadbeef8e814d72017-01-13 11:34:39 -0800865 // Provide a more specific error message for the RTCP mux "require" policy
866 // case.
zstein56162b92017-04-24 16:54:35 -0700867 if (rtcp_mux_required_ && !enable) {
deadbeef8e814d72017-01-13 11:34:39 -0800868 SafeSetError(
869 "rtcpMuxPolicy is 'require', but media description does not "
870 "contain 'a=rtcp-mux'.",
871 error_desc);
872 return false;
873 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874 bool ret = false;
Steve Anton3828c062017-12-06 10:34:51 -0800875 switch (type) {
876 case SdpType::kOffer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877 ret = rtcp_mux_filter_.SetOffer(enable, src);
878 break;
Steve Anton3828c062017-12-06 10:34:51 -0800879 case SdpType::kPrAnswer:
zhihuangb2cdd932017-01-19 16:54:25 -0800880 // This may activate RTCP muxing, but we don't yet destroy the transport
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700881 // because the final answer may deactivate it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
883 break;
Steve Anton3828c062017-12-06 10:34:51 -0800884 case SdpType::kAnswer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 ret = rtcp_mux_filter_.SetAnswer(enable, src);
886 if (ret && rtcp_mux_filter_.IsActive()) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800887 ActivateRtcpMux();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 }
889 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 default:
891 break;
892 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000893 if (!ret) {
894 SafeSetError("Failed to setup RTCP mux filter.", error_desc);
895 return false;
896 }
zsteine8ab5432017-07-12 11:48:11 -0700897 rtp_transport_->SetRtcpMuxEnabled(rtcp_mux_filter_.IsActive());
Steve Anton3828c062017-12-06 10:34:51 -0800898 // |rtcp_mux_filter_| can be active if |action| is SdpType::kPrAnswer or
899 // SdpType::kAnswer, but we only want to tear down the RTCP transport if we
900 // received a final answer.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000901 if (rtcp_mux_filter_.IsActive()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902 // If the RTP transport is already writable, then so are we.
zsteine8ab5432017-07-12 11:48:11 -0700903 if (rtp_transport_->rtp_packet_transport()->writable()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200904 ChannelWritable_n();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 }
906 }
907
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000908 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700912 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800913 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914}
915
Peter Boström0c4e06b2015-10-07 12:23:21 +0200916bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700917 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 return media_channel()->RemoveRecvStream(ssrc);
919}
920
921bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800922 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000923 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924 // Check for streams that have been removed.
925 bool ret = true;
926 for (StreamParamsVec::const_iterator it = local_streams_.begin();
927 it != local_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000928 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000929 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000930 std::ostringstream desc;
931 desc << "Failed to remove send stream with ssrc "
932 << it->first_ssrc() << ".";
933 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934 ret = false;
935 }
936 }
937 }
938 // Check for new streams.
939 for (StreamParamsVec::const_iterator it = streams.begin();
940 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000941 if (!GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100943 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000945 std::ostringstream desc;
946 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
947 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948 ret = false;
949 }
950 }
951 }
952 local_streams_ = streams;
953 return ret;
954}
955
956bool BaseChannel::UpdateRemoteStreams_w(
957 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800958 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000959 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960 // Check for streams that have been removed.
961 bool ret = true;
962 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
963 it != remote_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000964 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965 if (!RemoveRecvStream_w(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966 std::ostringstream desc;
967 desc << "Failed to remove remote stream with ssrc "
968 << it->first_ssrc() << ".";
969 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970 ret = false;
971 }
972 }
973 }
974 // Check for new streams.
975 for (StreamParamsVec::const_iterator it = streams.begin();
976 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000977 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978 if (AddRecvStream_w(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100979 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000981 std::ostringstream desc;
982 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
983 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984 ret = false;
985 }
986 }
987 }
988 remote_streams_ = streams;
989 return ret;
990}
991
jbauch5869f502017-06-29 12:31:36 -0700992RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
993 const RtpHeaderExtensions& extensions) {
994 if (!rtp_dtls_transport_ ||
995 !rtp_dtls_transport_->crypto_options()
996 .enable_encrypted_rtp_header_extensions) {
997 RtpHeaderExtensions filtered;
998 auto pred = [](const webrtc::RtpExtension& extension) {
999 return !extension.encrypt;
1000 };
1001 std::copy_if(extensions.begin(), extensions.end(),
1002 std::back_inserter(filtered), pred);
1003 return filtered;
1004 }
1005
1006 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
1007}
1008
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001009void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
isheriff6f8d6862016-05-26 11:24:55 -07001010 const std::vector<webrtc::RtpExtension>& extensions) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001011// Absolute Send Time extension id is used only with external auth,
1012// so do not bother searching for it and making asyncronious call to set
1013// something that is not used.
1014#if defined(ENABLE_EXTERNAL_AUTH)
isheriff6f8d6862016-05-26 11:24:55 -07001015 const webrtc::RtpExtension* send_time_extension =
jbauch5869f502017-06-29 12:31:36 -07001016 webrtc::RtpExtension::FindHeaderExtensionByUri(
1017 extensions, webrtc::RtpExtension::kAbsSendTimeUri);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001018 int rtp_abs_sendtime_extn_id =
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001019 send_time_extension ? send_time_extension->id : -1;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001020 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001021 RTC_FROM_HERE, network_thread_,
1022 Bind(&BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n, this,
1023 rtp_abs_sendtime_extn_id));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001024#endif
1025}
1026
1027void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
1028 int rtp_abs_sendtime_extn_id) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001029 if (sdes_transport_) {
1030 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
Zhi Huangcf990f52017-09-22 12:12:30 -07001031 rtp_abs_sendtime_extn_id);
Zhi Huang2a4d70c2017-11-29 15:41:59 -08001032 } else if (dtls_srtp_transport_) {
1033 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
1034 rtp_abs_sendtime_extn_id);
Zhi Huangcf990f52017-09-22 12:12:30 -07001035 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001036 RTC_LOG(LS_WARNING)
1037 << "Trying to cache the Absolute Send Time extension id "
1038 "but the SRTP is not active.";
Zhi Huangcf990f52017-09-22 12:12:30 -07001039 }
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001040}
1041
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001042void BaseChannel::OnMessage(rtc::Message *pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +01001043 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001045 case MSG_SEND_RTP_PACKET:
1046 case MSG_SEND_RTCP_PACKET: {
1047 RTC_DCHECK(network_thread_->IsCurrent());
1048 SendPacketMessageData* data =
1049 static_cast<SendPacketMessageData*>(pmsg->pdata);
1050 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
1051 SendPacket(rtcp, &data->packet, data->options);
1052 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053 break;
1054 }
1055 case MSG_FIRSTPACKETRECEIVED: {
1056 SignalFirstPacketReceived(this);
1057 break;
1058 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059 }
1060}
1061
zstein3dcf0e92017-06-01 13:22:42 -07001062void BaseChannel::AddHandledPayloadType(int payload_type) {
zsteine8ab5432017-07-12 11:48:11 -07001063 rtp_transport_->AddHandledPayloadType(payload_type);
zstein3dcf0e92017-06-01 13:22:42 -07001064}
1065
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001066void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067 // Flush all remaining RTCP messages. This should only be called in
1068 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001069 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001070 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001071 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
1072 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001073 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
1074 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001075 }
1076}
1077
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001078void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001079 RTC_DCHECK(network_thread_->IsCurrent());
1080 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001081 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001082 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
1083}
1084
1085void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
1086 RTC_DCHECK(worker_thread_->IsCurrent());
1087 SignalSentPacket(sent_packet);
1088}
1089
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001090void BaseChannel::UpdateEncryptedHeaderExtensionIds(
Zhi Huangc99b6c72017-11-10 16:44:46 -08001091 cricket::ContentSource source,
1092 const std::vector<int>& extension_ids) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001093 if (source == ContentSource::CS_LOCAL) {
1094 cached_recv_extension_ids_ = std::move(extension_ids);
1095 if (dtls_srtp_transport_) {
1096 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
1097 extension_ids);
1098 }
1099 } else {
1100 cached_send_extension_ids_ = std::move(extension_ids);
1101 if (dtls_srtp_transport_) {
1102 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
1103 extension_ids);
1104 }
1105 }
Zhi Huangc99b6c72017-11-10 16:44:46 -08001106}
1107
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001108void BaseChannel::ActivateRtcpMux() {
1109 // We permanently activated RTCP muxing; signal that we no longer need
1110 // the RTCP transport.
1111 std::string debug_name =
1112 transport_name_.empty()
1113 ? rtp_transport_->rtp_packet_transport()->transport_name()
1114 : transport_name_;
1115 RTC_LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
1116 << "; no longer need RTCP transport for " << debug_name;
1117 if (rtp_transport_->rtcp_packet_transport()) {
1118 SetTransport_n(/*rtcp=*/true, nullptr, nullptr);
1119 if (dtls_srtp_transport_) {
1120 RTC_DCHECK(rtp_dtls_transport_);
1121 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
1122 /*rtcp_dtls_transport_=*/nullptr);
1123 } else {
1124 rtp_transport_->SetRtcpPacketTransport(nullptr);
1125 }
1126 SignalRtcpMuxFullyActive(transport_name_);
Zhi Huangc99b6c72017-11-10 16:44:46 -08001127 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001128 UpdateWritableState_n();
Zhi Huangc99b6c72017-11-10 16:44:46 -08001129}
1130
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001131VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
1132 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001133 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134 MediaEngineInterface* media_engine,
Steve Anton8699a322017-11-06 15:53:33 -08001135 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001136 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001137 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001138 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001139 : BaseChannel(worker_thread,
1140 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001141 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001142 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001143 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001144 rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001145 srtp_required),
Steve Anton8699a322017-11-06 15:53:33 -08001146 media_engine_(media_engine) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001147
1148VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001149 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001150 StopAudioMonitor();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001151 // this can't be done in the base class, since it calls a virtual
1152 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001153 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001154}
1155
Peter Boström0c4e06b2015-10-07 12:23:21 +02001156bool VoiceChannel::SetAudioSend(uint32_t ssrc,
solenbergdfc8f4f2015-10-01 02:31:10 -07001157 bool enable,
solenberg1dd98f32015-09-10 01:57:14 -07001158 const AudioOptions* options,
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001159 AudioSource* source) {
stefanf79ade12017-06-02 06:44:03 -07001160 return InvokeOnWorker<bool>(
1161 RTC_FROM_HERE, Bind(&VoiceMediaChannel::SetAudioSend, media_channel(),
1162 ssrc, enable, options, source));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001163}
1164
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001165// TODO(juberti): Handle early media the right way. We should get an explicit
1166// ringing message telling us to start playing local ringback, which we cancel
1167// if any early media actually arrives. For now, we do the opposite, which is
1168// to wait 1 second for early media, and start playing local ringback if none
1169// arrives.
1170void VoiceChannel::SetEarlyMedia(bool enable) {
1171 if (enable) {
1172 // Start the early media timeout
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001173 worker_thread()->PostDelayed(RTC_FROM_HERE, kEarlyMediaTimeout, this,
1174 MSG_EARLYMEDIATIMEOUT);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001175 } else {
1176 // Stop the timeout if currently going.
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001177 worker_thread()->Clear(this, MSG_EARLYMEDIATIMEOUT);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001178 }
1179}
1180
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001181bool VoiceChannel::GetStats(VoiceMediaInfo* stats) {
stefanf79ade12017-06-02 06:44:03 -07001182 return InvokeOnWorker<bool>(RTC_FROM_HERE, Bind(&VoiceMediaChannel::GetStats,
1183 media_channel(), stats));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001184}
1185
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001186void VoiceChannel::StartAudioMonitor(int cms) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001187 audio_monitor_.reset(new AudioMonitor(this, rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001188 audio_monitor_->Start(cms);
1189}
1190
1191void VoiceChannel::StopAudioMonitor() {
1192 if (audio_monitor_) {
1193 audio_monitor_->Stop();
1194 audio_monitor_.reset();
1195 }
1196}
1197
1198bool VoiceChannel::IsAudioMonitorRunning() const {
1199 return (audio_monitor_.get() != NULL);
1200}
1201
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001202int VoiceChannel::GetInputLevel_w() {
Fredrik Solenberg0c022642015-08-05 12:25:22 +02001203 return media_engine_->GetInputLevel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001204}
1205
1206int VoiceChannel::GetOutputLevel_w() {
1207 return media_channel()->GetOutputLevel();
1208}
1209
1210void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) {
1211 media_channel()->GetActiveStreams(actives);
1212}
1213
zstein3dcf0e92017-06-01 13:22:42 -07001214void VoiceChannel::OnPacketReceived(bool rtcp,
zstein634977b2017-07-14 12:30:04 -07001215 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -07001216 const rtc::PacketTime& packet_time) {
1217 BaseChannel::OnPacketReceived(rtcp, packet, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001218 // Set a flag when we've received an RTP packet. If we're waiting for early
1219 // media, this will disable the timeout.
zstein3dcf0e92017-06-01 13:22:42 -07001220 if (!received_media_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221 received_media_ = true;
1222 }
1223}
1224
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001225void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001226 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001227 invoker_.AsyncInvoke<void>(
1228 RTC_FROM_HERE, worker_thread_,
1229 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001230}
1231
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001232void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001233 // Render incoming data if we're the active call, and we have the local
1234 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001235 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -07001236 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001237
1238 // Send outgoing data if we're the active call, we have the remote content,
1239 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001240 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001241 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242
Mirko Bonadei675513b2017-11-09 11:09:25 +01001243 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001244}
1245
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001246bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001247 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001248 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001249 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001250 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001251 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001252
Steve Antonb1c1de12017-12-21 15:14:30 -08001253 RTC_DCHECK(content);
1254 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001255 SafeSetError("Can't find audio content in local description.", error_desc);
1256 return false;
1257 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001258
Steve Antonb1c1de12017-12-21 15:14:30 -08001259 const AudioContentDescription* audio = content->as_audio();
1260
jbauch5869f502017-06-29 12:31:36 -07001261 RtpHeaderExtensions rtp_header_extensions =
1262 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
1263
Steve Anton3828c062017-12-06 10:34:51 -08001264 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1265 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001266 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001267 }
1268
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001269 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001270 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001271 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001272 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001273 error_desc);
1274 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001275 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001276 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001277 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001278 }
1279 last_recv_params_ = recv_params;
1280
1281 // TODO(pthatcher): Move local streams into AudioSendParameters, and
1282 // only give it to the media channel once we have a remote
1283 // description too (without a remote description, we won't be able
1284 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001285 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001286 SafeSetError("Failed to set local audio description streams.", error_desc);
1287 return false;
1288 }
1289
1290 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001291 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001292 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293}
1294
1295bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001296 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001297 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001298 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001299 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001300 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301
Steve Antonb1c1de12017-12-21 15:14:30 -08001302 RTC_DCHECK(content);
1303 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001304 SafeSetError("Can't find audio content in remote description.", error_desc);
1305 return false;
1306 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307
Steve Antonb1c1de12017-12-21 15:14:30 -08001308 const AudioContentDescription* audio = content->as_audio();
1309
jbauch5869f502017-06-29 12:31:36 -07001310 RtpHeaderExtensions rtp_header_extensions =
1311 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
1312
Steve Anton3828c062017-12-06 10:34:51 -08001313 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1314 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001315 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316 }
1317
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001318 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001319 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
1320 &send_params);
skvladdc1c62c2016-03-16 19:07:43 -07001321
1322 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1323 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001324 SafeSetError("Failed to set remote audio description send parameters.",
1325 error_desc);
1326 return false;
1327 }
1328 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001330 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
1331 // and only give it to the media channel once we have a local
1332 // description too (without a local description, we won't be able to
1333 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001334 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001335 SafeSetError("Failed to set remote audio description streams.", error_desc);
1336 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337 }
1338
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001339 if (audio->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001340 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001341 }
1342
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001343 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001344 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001345 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346}
1347
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348void VoiceChannel::HandleEarlyMediaTimeout() {
1349 // This occurs on the main thread, not the worker thread.
1350 if (!received_media_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001351 RTC_LOG(LS_INFO) << "No early media received before timeout";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001352 SignalEarlyMediaTimeout(this);
1353 }
1354}
1355
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001356void VoiceChannel::OnMessage(rtc::Message *pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357 switch (pmsg->message_id) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358 case MSG_EARLYMEDIATIMEOUT:
1359 HandleEarlyMediaTimeout();
1360 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361 default:
1362 BaseChannel::OnMessage(pmsg);
1363 break;
1364 }
1365}
1366
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001367VideoChannel::VideoChannel(rtc::Thread* worker_thread,
1368 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001369 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001370 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001371 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001372 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001373 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001374 : BaseChannel(worker_thread,
1375 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001376 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001377 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001378 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001379 rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001380 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001383 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384 // this can't be done in the base class, since it calls a virtual
1385 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001386
1387 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388}
1389
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001390void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391 // Send outgoing data if we're the active call, we have the remote content,
1392 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001393 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001394 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001395 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396 // TODO(gangji): Report error back to server.
1397 }
1398
Mirko Bonadei675513b2017-11-09 11:09:25 +01001399 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400}
1401
stefanf79ade12017-06-02 06:44:03 -07001402void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1403 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1404 media_channel(), bwe_info));
1405}
1406
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001407bool VideoChannel::GetStats(VideoMediaInfo* stats) {
stefanf79ade12017-06-02 06:44:03 -07001408 return InvokeOnWorker<bool>(RTC_FROM_HERE, Bind(&VideoMediaChannel::GetStats,
1409 media_channel(), stats));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410}
1411
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001413 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001414 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001415 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001416 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001417 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001418
Steve Antonb1c1de12017-12-21 15:14:30 -08001419 RTC_DCHECK(content);
1420 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001421 SafeSetError("Can't find video content in local description.", error_desc);
1422 return false;
1423 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424
Steve Antonb1c1de12017-12-21 15:14:30 -08001425 const VideoContentDescription* video = content->as_video();
1426
jbauch5869f502017-06-29 12:31:36 -07001427 RtpHeaderExtensions rtp_header_extensions =
1428 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1429
Steve Anton3828c062017-12-06 10:34:51 -08001430 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1431 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001432 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433 }
1434
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001435 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001436 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001437 if (!media_channel()->SetRecvParameters(recv_params)) {
1438 SafeSetError("Failed to set local video description recv parameters.",
1439 error_desc);
1440 return false;
1441 }
1442 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001443 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001444 }
1445 last_recv_params_ = recv_params;
1446
1447 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1448 // only give it to the media channel once we have a remote
1449 // description too (without a remote description, we won't be able
1450 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001451 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001452 SafeSetError("Failed to set local video description streams.", error_desc);
1453 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454 }
1455
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001456 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001457 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001458 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459}
1460
1461bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001462 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001463 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001464 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001465 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001466 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467
Steve Antonb1c1de12017-12-21 15:14:30 -08001468 RTC_DCHECK(content);
1469 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001470 SafeSetError("Can't find video content in remote description.", error_desc);
1471 return false;
1472 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473
Steve Antonb1c1de12017-12-21 15:14:30 -08001474 const VideoContentDescription* video = content->as_video();
1475
jbauch5869f502017-06-29 12:31:36 -07001476 RtpHeaderExtensions rtp_header_extensions =
1477 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1478
Steve Anton3828c062017-12-06 10:34:51 -08001479 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1480 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001481 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482 }
1483
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001484 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001485 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
1486 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001487 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001488 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001489 }
skvladdc1c62c2016-03-16 19:07:43 -07001490
1491 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1492
1493 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001494 SafeSetError("Failed to set remote video description send parameters.",
1495 error_desc);
1496 return false;
1497 }
1498 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001500 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1501 // and only give it to the media channel once we have a local
1502 // description too (without a local description, we won't be able to
1503 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001504 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001505 SafeSetError("Failed to set remote video description streams.", error_desc);
1506 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001507 }
1508
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001509 if (video->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001510 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001512
1513 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001514 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001515 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
deadbeef953c2ce2017-01-09 14:53:41 -08001518RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1519 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001520 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001521 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001522 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001523 bool rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001524 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001525 : BaseChannel(worker_thread,
1526 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001527 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001528 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001529 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001530 rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001531 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532
deadbeef953c2ce2017-01-09 14:53:41 -08001533RtpDataChannel::~RtpDataChannel() {
1534 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535 // this can't be done in the base class, since it calls a virtual
1536 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001537
1538 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539}
1540
Steve Anton8699a322017-11-06 15:53:33 -08001541void RtpDataChannel::Init_w(
deadbeeff5346592017-01-24 21:51:21 -08001542 DtlsTransportInternal* rtp_dtls_transport,
1543 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -08001544 rtc::PacketTransportInternal* rtp_packet_transport,
1545 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -08001546 BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport,
1547 rtp_packet_transport, rtcp_packet_transport);
1548
deadbeef953c2ce2017-01-09 14:53:41 -08001549 media_channel()->SignalDataReceived.connect(this,
1550 &RtpDataChannel::OnDataReceived);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001551 media_channel()->SignalReadyToSend.connect(
deadbeef953c2ce2017-01-09 14:53:41 -08001552 this, &RtpDataChannel::OnDataChannelReadyToSend);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553}
1554
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001555void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1556 BaseChannel::Init_w(rtp_transport);
1557 media_channel()->SignalDataReceived.connect(this,
1558 &RtpDataChannel::OnDataReceived);
1559 media_channel()->SignalReadyToSend.connect(
1560 this, &RtpDataChannel::OnDataChannelReadyToSend);
1561}
1562
deadbeef953c2ce2017-01-09 14:53:41 -08001563bool RtpDataChannel::SendData(const SendDataParams& params,
1564 const rtc::CopyOnWriteBuffer& payload,
1565 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001566 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001567 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1568 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569}
1570
deadbeef953c2ce2017-01-09 14:53:41 -08001571bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001572 const DataContentDescription* content,
1573 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1575 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001576 // It's been set before, but doesn't match. That's bad.
1577 if (is_sctp) {
1578 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1579 error_desc);
1580 return false;
1581 }
1582 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
deadbeef953c2ce2017-01-09 14:53:41 -08001585bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001586 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001587 std::string* error_desc) {
1588 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001589 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001590 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591
Steve Antonb1c1de12017-12-21 15:14:30 -08001592 RTC_DCHECK(content);
1593 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001594 SafeSetError("Can't find data content in local description.", error_desc);
1595 return false;
1596 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597
Steve Antonb1c1de12017-12-21 15:14:30 -08001598 const DataContentDescription* data = content->as_data();
1599
deadbeef953c2ce2017-01-09 14:53:41 -08001600 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601 return false;
1602 }
1603
jbauch5869f502017-06-29 12:31:36 -07001604 RtpHeaderExtensions rtp_header_extensions =
1605 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1606
Steve Anton3828c062017-12-06 10:34:51 -08001607 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1608 error_desc)) {
deadbeef953c2ce2017-01-09 14:53:41 -08001609 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610 }
1611
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001612 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001613 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001614 if (!media_channel()->SetRecvParameters(recv_params)) {
1615 SafeSetError("Failed to set remote data description recv parameters.",
1616 error_desc);
1617 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618 }
deadbeef953c2ce2017-01-09 14:53:41 -08001619 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001620 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001621 }
1622 last_recv_params_ = recv_params;
1623
1624 // TODO(pthatcher): Move local streams into DataSendParameters, and
1625 // only give it to the media channel once we have a remote
1626 // description too (without a remote description, we won't be able
1627 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001628 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001629 SafeSetError("Failed to set local data description streams.", error_desc);
1630 return false;
1631 }
1632
1633 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001634 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001635 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001636}
1637
deadbeef953c2ce2017-01-09 14:53:41 -08001638bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001639 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001640 std::string* error_desc) {
1641 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001642 RTC_DCHECK_RUN_ON(worker_thread());
1643 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001644
Steve Antonb1c1de12017-12-21 15:14:30 -08001645 RTC_DCHECK(content);
1646 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001647 SafeSetError("Can't find data content in remote description.", error_desc);
1648 return false;
1649 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001650
Steve Antonb1c1de12017-12-21 15:14:30 -08001651 const DataContentDescription* data = content->as_data();
1652
Zhi Huang801b8682017-11-15 11:36:43 -08001653 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1654 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001655 return true;
1656 }
1657
deadbeef953c2ce2017-01-09 14:53:41 -08001658 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001659 return false;
1660 }
1661
jbauch5869f502017-06-29 12:31:36 -07001662 RtpHeaderExtensions rtp_header_extensions =
1663 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1664
Mirko Bonadei675513b2017-11-09 11:09:25 +01001665 RTC_LOG(LS_INFO) << "Setting remote data description";
Steve Anton3828c062017-12-06 10:34:51 -08001666 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1667 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001668 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001669 }
1670
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001671 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001672 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
1673 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001674 if (!media_channel()->SetSendParameters(send_params)) {
1675 SafeSetError("Failed to set remote data description send parameters.",
1676 error_desc);
1677 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001679 last_send_params_ = send_params;
1680
1681 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1682 // and only give it to the media channel once we have a local
1683 // description too (without a local description, we won't be able to
1684 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001685 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001686 SafeSetError("Failed to set remote data description streams.",
1687 error_desc);
1688 return false;
1689 }
1690
1691 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001692 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001693 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001694}
1695
deadbeef953c2ce2017-01-09 14:53:41 -08001696void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697 // Render incoming data if we're the active call, and we have the local
1698 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001699 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001701 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702 }
1703
1704 // Send outgoing data if we're the active call, we have the remote content,
1705 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001706 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001707 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001708 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709 }
1710
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001711 // Trigger SignalReadyToSendData asynchronously.
1712 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001713
Mirko Bonadei675513b2017-11-09 11:09:25 +01001714 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715}
1716
deadbeef953c2ce2017-01-09 14:53:41 -08001717void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001718 switch (pmsg->message_id) {
1719 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001720 DataChannelReadyToSendMessageData* data =
1721 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001722 ready_to_send_data_ = data->data();
1723 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724 delete data;
1725 break;
1726 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727 case MSG_DATARECEIVED: {
1728 DataReceivedMessageData* data =
1729 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001730 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731 delete data;
1732 break;
1733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734 default:
1735 BaseChannel::OnMessage(pmsg);
1736 break;
1737 }
1738}
1739
deadbeef953c2ce2017-01-09 14:53:41 -08001740void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1741 const char* data,
1742 size_t len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743 DataReceivedMessageData* msg = new DataReceivedMessageData(
1744 params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001745 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001746}
1747
deadbeef953c2ce2017-01-09 14:53:41 -08001748void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001749 // This is usded for congestion control to indicate that the stream is ready
1750 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1751 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001752 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001753 new DataChannelReadyToSendMessageData(writable));
1754}
1755
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756} // namespace cricket