blob: 2aab718ec853c909beccc819e81c687961ce7e17 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
jbauch5869f502017-06-29 12:31:36 -070011#include <algorithm>
12#include <iterator>
kwiberg0eb15ed2015-12-17 03:04:15 -080013#include <utility>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "pc/channel.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/call/audio_sink.h"
18#include "media/base/mediaconstants.h"
19#include "media/base/rtputils.h"
20#include "rtc_base/bind.h"
21#include "rtc_base/byteorder.h"
22#include "rtc_base/checks.h"
23#include "rtc_base/copyonwritebuffer.h"
24#include "rtc_base/dscp.h"
25#include "rtc_base/logging.h"
26#include "rtc_base/networkroute.h"
27#include "rtc_base/ptr_util.h"
28#include "rtc_base/trace_event.h"
Patrik Höglund42805f32018-01-18 19:15:38 +000029// Adding 'nogncheck' to disable the gn include headers check to support modular
30// WebRTC build targets.
31#include "media/engine/webrtcvoiceengine.h" // nogncheck
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "p2p/base/packettransportinternal.h"
33#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080034#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
36namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000037using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080038using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000039
deadbeef2d110be2016-01-13 12:00:26 -080040namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020041
42struct SendPacketMessageData : public rtc::MessageData {
43 rtc::CopyOnWriteBuffer packet;
44 rtc::PacketOptions options;
45};
46
deadbeef2d110be2016-01-13 12:00:26 -080047} // namespace
48
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049enum {
Steve Anton0807d152018-03-05 11:23:09 -080050 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020051 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055};
56
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000057static void SafeSetError(const std::string& message, std::string* error_desc) {
58 if (error_desc) {
59 *error_desc = message;
60 }
61}
62
jbaucheec21bd2016-03-20 06:15:43 -070063static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070065 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066}
67
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070068template <class Codec>
69void RtpParametersFromMediaDescription(
70 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070071 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070072 RtpParameters<Codec>* params) {
73 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080074 // a description without codecs. Currently the ORTC implementation is relying
75 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070076 if (desc->has_codecs()) {
77 params->codecs = desc->codecs();
78 }
79 // TODO(pthatcher): See if we really need
80 // rtp_header_extensions_set() and remove it if we don't.
81 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070082 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070083 }
deadbeef13871492015-12-09 12:37:51 -080084 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070085}
86
nisse05103312016-03-16 02:22:50 -070087template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070088void RtpSendParametersFromMediaDescription(
89 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070090 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070091 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070092 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070093 send_params->max_bandwidth_bps = desc->bandwidth();
94}
95
Danil Chapovalov33b01f22016-05-11 19:55:27 +020096BaseChannel::BaseChannel(rtc::Thread* worker_thread,
97 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -080098 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -080099 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700100 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700101 bool srtp_required,
102 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200103 : worker_thread_(worker_thread),
104 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800105 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000106 content_name_(content_name),
deadbeef7af91dd2016-12-13 11:29:11 -0800107 srtp_required_(srtp_required),
Zhi Huange830e682018-03-30 10:48:35 -0700108 crypto_options_(crypto_options),
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_);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100111 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112}
113
114BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800115 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800116 RTC_DCHECK_RUN_ON(worker_thread_);
wu@webrtc.org78187522013-10-07 23:32:02 +0000117 Deinit();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200118 // Eats any outstanding messages or packets.
119 worker_thread_->Clear(&invoker_);
120 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121 // We must destroy the media channel before the transport channel, otherwise
122 // the media channel may try to send on the dead transport channel. NULLing
123 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800124 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100125 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200126}
127
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800128void BaseChannel::ConnectToRtpTransport() {
129 RTC_DCHECK(rtp_transport_);
130 rtp_transport_->SignalReadyToSend.connect(
131 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000132 // TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
133 // with a callback interface later so that the demuxer can select which
134 // channel to signal.
135 rtp_transport_->SignalPacketReceived.connect(this,
136 &BaseChannel::OnPacketReceived);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800137 rtp_transport_->SignalNetworkRouteChanged.connect(
138 this, &BaseChannel::OnNetworkRouteChanged);
139 rtp_transport_->SignalWritableState.connect(this,
140 &BaseChannel::OnWritableState);
141 rtp_transport_->SignalSentPacket.connect(this,
142 &BaseChannel::SignalSentPacket_n);
Steve Antondb67ba12018-03-19 17:41:42 -0700143 // TODO(bugs.webrtc.org/8587): Set the metrics observer through
144 // JsepTransportController once it takes responsibility for creating
145 // RtpTransports.
146 if (metrics_observer_) {
147 rtp_transport_->SetMetricsObserver(metrics_observer_);
148 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800149}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200150
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800151void BaseChannel::DisconnectFromRtpTransport() {
152 RTC_DCHECK(rtp_transport_);
153 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000154 rtp_transport_->SignalPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800155 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
156 rtp_transport_->SignalWritableState.disconnect(this);
157 rtp_transport_->SignalSentPacket.disconnect(this);
Steve Antondb67ba12018-03-19 17:41:42 -0700158 rtp_transport_->SetMetricsObserver(nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200159}
160
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800161void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
162 RTC_DCHECK_RUN_ON(worker_thread_);
163 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
164 SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800165 });
166
167 // Both RTP and RTCP channels should be set, we can call SetInterface on
168 // the media channel and it can set network options.
169 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200170}
171
wu@webrtc.org78187522013-10-07 23:32:02 +0000172void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200173 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000174 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200175 // Packets arrive on the network thread, processing packets calls virtual
176 // functions, so need to stop this process in Deinit that is called in
177 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800178 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000179 FlushRtcpMessages_n();
Zhi Huang27f3bf52018-03-26 21:37:23 -0700180
Zhi Huange830e682018-03-30 10:48:35 -0700181 if (rtp_transport_) {
182 DisconnectFromRtpTransport();
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000183 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800184 // Clear pending read packets/messages.
185 network_thread_->Clear(&invoker_);
186 network_thread_->Clear(this);
187 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000188}
189
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800190void BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
191 if (!network_thread_->IsCurrent()) {
192 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
193 SetRtpTransport(rtp_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800194 });
Zhi Huange830e682018-03-30 10:48:35 -0700195 return;
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800196 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000197
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800198 if (rtp_transport_) {
199 DisconnectFromRtpTransport();
200 }
Zhi Huange830e682018-03-30 10:48:35 -0700201
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800202 rtp_transport_ = rtp_transport;
Zhi Huange830e682018-03-30 10:48:35 -0700203 if (rtp_transport_) {
204 RTC_DCHECK(rtp_transport_->rtp_packet_transport());
205 transport_name_ = rtp_transport_->rtp_packet_transport()->transport_name();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800206
Zhi Huange830e682018-03-30 10:48:35 -0700207 ConnectToRtpTransport();
208 OnTransportReadyToSend(rtp_transport_->IsReadyToSend());
209 UpdateWritableState_n();
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800210
Zhi Huange830e682018-03-30 10:48:35 -0700211 // Set the cached socket options.
212 for (const auto& pair : socket_options_) {
213 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
214 pair.second);
215 }
216 if (rtp_transport_->rtcp_packet_transport()) {
217 for (const auto& pair : rtcp_socket_options_) {
218 rtp_transport_->rtp_packet_transport()->SetOption(pair.first,
219 pair.second);
220 }
221 }
guoweis46383312015-12-17 16:45:59 -0800222 }
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000223}
224
Steve Antondb67ba12018-03-19 17:41:42 -0700225void BaseChannel::SetMetricsObserver(
226 rtc::scoped_refptr<webrtc::MetricsObserverInterface> metrics_observer) {
227 metrics_observer_ = metrics_observer;
228 if (rtp_transport_) {
229 rtp_transport_->SetMetricsObserver(metrics_observer);
230 }
231}
232
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700234 worker_thread_->Invoke<void>(
235 RTC_FROM_HERE,
236 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
237 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 return true;
239}
240
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241bool BaseChannel::AddRecvStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700242 return InvokeOnWorker<bool>(RTC_FROM_HERE,
243 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244}
245
Peter Boström0c4e06b2015-10-07 12:23:21 +0200246bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700247 return InvokeOnWorker<bool>(
248 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249}
250
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000251bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700252 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700253 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000254}
255
Peter Boström0c4e06b2015-10-07 12:23:21 +0200256bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700257 return InvokeOnWorker<bool>(
258 RTC_FROM_HERE,
259 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000260}
261
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800263 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000264 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100265 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700266 return InvokeOnWorker<bool>(
267 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800268 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269}
270
271bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800272 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000273 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100274 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700275 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800276 RTC_FROM_HERE,
277 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278}
279
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700280bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800282 return enabled() &&
283 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284}
285
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700286bool BaseChannel::IsReadyToSendMedia_w() const {
287 // Need to access some state updated on the network thread.
288 return network_thread_->Invoke<bool>(
289 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
290}
291
292bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 // Send outgoing data if we are enabled, have local and remote content,
294 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800295 return enabled() &&
296 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
297 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huange830e682018-03-30 10:48:35 -0700298 was_ever_writable() && (srtp_active() || encryption_disabled_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299}
300
jbaucheec21bd2016-03-20 06:15:43 -0700301bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700302 const rtc::PacketOptions& options) {
303 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
jbaucheec21bd2016-03-20 06:15:43 -0700306bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700307 const rtc::PacketOptions& options) {
308 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309}
310
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200313 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700314 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200315}
316
317int BaseChannel::SetOption_n(SocketType type,
318 rtc::Socket::Option opt,
319 int value) {
320 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huange830e682018-03-30 10:48:35 -0700321 RTC_DCHECK(rtp_transport_);
deadbeef5bd5ca32017-02-10 11:31:50 -0800322 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000324 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700325 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700326 socket_options_.push_back(
327 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000328 break;
329 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700330 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700331 rtcp_socket_options_.push_back(
332 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000333 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 }
deadbeeff5346592017-01-24 21:51:21 -0800335 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336}
337
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800338void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200339 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800340 if (writable) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800341 ChannelWritable_n();
342 } else {
343 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800344 }
345}
346
Zhi Huang942bc2e2017-11-13 13:26:07 -0800347void BaseChannel::OnNetworkRouteChanged(
348 rtc::Optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200349 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800350 rtc::NetworkRoute new_route;
351 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800352 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000353 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800354 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
355 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
356 // work correctly. Intentionally leave it broken to simplify the code and
357 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800358 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800359 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800360 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700361}
362
zstein56162b92017-04-24 16:54:35 -0700363void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800364 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
365 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366}
367
stefanc1aeaf02015-10-15 07:26:07 -0700368bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700369 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700370 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200371 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
372 // If the thread is not our network thread, we will post to our network
373 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 // synchronize access to all the pieces of the send path, including
375 // SRTP and the inner workings of the transport channels.
376 // The only downside is that we can't return a proper failure code if
377 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200378 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200380 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
381 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800382 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700383 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700384 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385 return true;
386 }
Zhi Huange830e682018-03-30 10:48:35 -0700387
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200388 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389
390 // Now that we are on the correct thread, ensure we have a place to send this
391 // packet before doing anything. (We might get RTCP packets that we don't
392 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
393 // transport.
Zhi Huange830e682018-03-30 10:48:35 -0700394 if (!rtp_transport_ || !rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 return false;
396 }
397
398 // Protect ourselves against crazy data.
399 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100400 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
401 << RtpRtcpStringLiteral(rtcp)
402 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 return false;
404 }
405
Zhi Huangcf990f52017-09-22 12:12:30 -0700406 if (!srtp_active()) {
407 if (srtp_required_) {
408 // The audio/video engines may attempt to send RTCP packets as soon as the
409 // streams are created, so don't treat this as an error for RTCP.
410 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
411 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412 return false;
413 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700414 // However, there shouldn't be any RTP packets sent before SRTP is set up
415 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100416 RTC_LOG(LS_ERROR)
417 << "Can't send outgoing RTP packet when SRTP is inactive"
418 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700419 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800420 return false;
421 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800422
423 std::string packet_type = rtcp ? "RTCP" : "RTP";
424 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
425 << " packet without encryption.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 }
Zhi Huange830e682018-03-30 10:48:35 -0700427
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000428 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800429 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
430 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431}
432
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000433bool BaseChannel::HandlesPayloadType(int packet_type) const {
Zhi Huange830e682018-03-30 10:48:35 -0700434 return bundle_filter_.FindPayloadType(packet_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000435}
436
zstein3dcf0e92017-06-01 13:22:42 -0700437void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000438 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -0700439 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000440 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700442 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443 }
444
Zhi Huange830e682018-03-30 10:48:35 -0700445 // Filter out the packet this channel cannot handle.
446 if (!rtcp && !bundle_filter_.DemuxPacket(packet->data(), packet->size())) {
447 return;
448 }
449
Zhi Huangcf990f52017-09-22 12:12:30 -0700450 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000451 // Our session description indicates that SRTP is required, but we got a
452 // packet before our SRTP filter is active. This means either that
453 // a) we got SRTP packets before we received the SDES keys, in which case
454 // we can't decrypt it anyway, or
455 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800456 // transports, so we haven't yet extracted keys, even if DTLS did
457 // complete on the transport that the packets are being sent on. It's
458 // really good practice to wait for both RTP and RTCP to be good to go
459 // before sending media, to prevent weird failure modes, so it's fine
460 // for us to just eat packets here. This is all sidestepped if RTCP mux
461 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100462 RTC_LOG(LS_WARNING)
463 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
464 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000465 return;
466 }
467
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200468 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700469 RTC_FROM_HERE, worker_thread_,
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000470 Bind(&BaseChannel::ProcessPacket, this, rtcp, *packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200471}
472
zstein3dcf0e92017-06-01 13:22:42 -0700473void BaseChannel::ProcessPacket(bool rtcp,
474 const rtc::CopyOnWriteBuffer& packet,
475 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200476 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700477
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200478 // Need to copy variable because OnRtcpReceived/OnPacketReceived
479 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
480 rtc::CopyOnWriteBuffer data(packet);
481 if (rtcp) {
482 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000483 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200484 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000485 }
486}
487
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000488void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700489 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490 if (enabled_)
491 return;
492
Mirko Bonadei675513b2017-11-09 11:09:25 +0100493 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000494 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700495 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000496}
497
498void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700499 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000500 if (!enabled_)
501 return;
502
Mirko Bonadei675513b2017-11-09 11:09:25 +0100503 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700505 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506}
507
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200508void BaseChannel::UpdateWritableState_n() {
Zhi Huange830e682018-03-30 10:48:35 -0700509 if (rtp_transport_->IsWritable(/*rtcp=*/true) &&
510 rtp_transport_->IsWritable(/*rtcp=*/false)) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200511 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700512 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200513 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700514 }
515}
516
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200517void BaseChannel::ChannelWritable_n() {
518 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800519 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800521 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522
Mirko Bonadei675513b2017-11-09 11:09:25 +0100523 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
524 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000525
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 was_ever_writable_ = true;
527 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700528 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000529}
530
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200531void BaseChannel::ChannelNotWritable_n() {
532 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000533 if (!writable_)
534 return;
535
Mirko Bonadei675513b2017-11-09 11:09:25 +0100536 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700538 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539}
540
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700542 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800543 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544}
545
Peter Boström0c4e06b2015-10-07 12:23:21 +0200546bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700547 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548 return media_channel()->RemoveRecvStream(ssrc);
549}
550
551bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800552 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000553 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 // Check for streams that have been removed.
555 bool ret = true;
556 for (StreamParamsVec::const_iterator it = local_streams_.begin();
557 it != local_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000558 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000560 std::ostringstream desc;
561 desc << "Failed to remove send stream with ssrc "
562 << it->first_ssrc() << ".";
563 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 ret = false;
565 }
566 }
567 }
568 // Check for new streams.
569 for (StreamParamsVec::const_iterator it = streams.begin();
570 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000571 if (!GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100573 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000575 std::ostringstream desc;
576 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
577 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 ret = false;
579 }
580 }
581 }
582 local_streams_ = streams;
583 return ret;
584}
585
586bool BaseChannel::UpdateRemoteStreams_w(
587 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800588 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000589 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590 // Check for streams that have been removed.
591 bool ret = true;
592 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
593 it != remote_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000594 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595 if (!RemoveRecvStream_w(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000596 std::ostringstream desc;
597 desc << "Failed to remove remote stream with ssrc "
598 << it->first_ssrc() << ".";
599 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000600 ret = false;
601 }
602 }
603 }
604 // Check for new streams.
605 for (StreamParamsVec::const_iterator it = streams.begin();
606 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000607 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608 if (AddRecvStream_w(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100609 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000610 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000611 std::ostringstream desc;
612 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
613 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614 ret = false;
615 }
616 }
617 }
618 remote_streams_ = streams;
619 return ret;
620}
621
jbauch5869f502017-06-29 12:31:36 -0700622RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
623 const RtpHeaderExtensions& extensions) {
Zhi Huange830e682018-03-30 10:48:35 -0700624 RTC_DCHECK(rtp_transport_);
625 if (crypto_options_.enable_encrypted_rtp_header_extensions) {
jbauch5869f502017-06-29 12:31:36 -0700626 RtpHeaderExtensions filtered;
627 auto pred = [](const webrtc::RtpExtension& extension) {
628 return !extension.encrypt;
629 };
630 std::copy_if(extensions.begin(), extensions.end(),
631 std::back_inserter(filtered), pred);
632 return filtered;
633 }
634
635 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
636}
637
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000638void BaseChannel::OnMessage(rtc::Message *pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100639 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000640 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200641 case MSG_SEND_RTP_PACKET:
642 case MSG_SEND_RTCP_PACKET: {
643 RTC_DCHECK(network_thread_->IsCurrent());
644 SendPacketMessageData* data =
645 static_cast<SendPacketMessageData*>(pmsg->pdata);
646 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
647 SendPacket(rtcp, &data->packet, data->options);
648 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 break;
650 }
651 case MSG_FIRSTPACKETRECEIVED: {
652 SignalFirstPacketReceived(this);
653 break;
654 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655 }
656}
657
zstein3dcf0e92017-06-01 13:22:42 -0700658void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huange830e682018-03-30 10:48:35 -0700659 bundle_filter_.AddPayloadType(payload_type);
zstein3dcf0e92017-06-01 13:22:42 -0700660}
661
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200662void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663 // Flush all remaining RTCP messages. This should only be called in
664 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200665 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000666 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200667 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
668 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700669 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
670 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 }
672}
673
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800674void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200675 RTC_DCHECK(network_thread_->IsCurrent());
676 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700677 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200678 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
679}
680
681void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
682 RTC_DCHECK(worker_thread_->IsCurrent());
683 SignalSentPacket(sent_packet);
684}
685
686VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
687 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800688 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +0100689 // TODO(nisse): Delete unused argument.
690 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -0800691 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700693 bool srtp_required,
694 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200695 : BaseChannel(worker_thread,
696 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800697 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800698 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700699 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700700 srtp_required,
701 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702
703VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800704 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 // this can't be done in the base class, since it calls a virtual
706 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700707 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708}
709
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700710void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200711 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700712 invoker_.AsyncInvoke<void>(
713 RTC_FROM_HERE, worker_thread_,
714 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200715}
716
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700717void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 // Render incoming data if we're the active call, and we have the local
719 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700720 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -0700721 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722
723 // Send outgoing data if we're the active call, we have the remote content,
724 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700725 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800726 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727
Mirko Bonadei675513b2017-11-09 11:09:25 +0100728 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729}
730
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800732 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000733 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100734 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800735 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100736 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737
Steve Antonb1c1de12017-12-21 15:14:30 -0800738 RTC_DCHECK(content);
739 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000740 SafeSetError("Can't find audio content in local description.", error_desc);
741 return false;
742 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743
Steve Antonb1c1de12017-12-21 15:14:30 -0800744 const AudioContentDescription* audio = content->as_audio();
745
jbauch5869f502017-06-29 12:31:36 -0700746 RtpHeaderExtensions rtp_header_extensions =
747 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
748
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700749 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700750 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700751 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -0700752 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700753 error_desc);
754 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700756 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700757 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700758 }
759 last_recv_params_ = recv_params;
760
761 // TODO(pthatcher): Move local streams into AudioSendParameters, and
762 // only give it to the media channel once we have a remote
763 // description too (without a remote description, we won't be able
764 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800765 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700766 SafeSetError("Failed to set local audio description streams.", error_desc);
767 return false;
768 }
769
770 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700771 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700772 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773}
774
775bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800776 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000777 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100778 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800779 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100780 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781
Steve Antonb1c1de12017-12-21 15:14:30 -0800782 RTC_DCHECK(content);
783 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000784 SafeSetError("Can't find audio content in remote description.", error_desc);
785 return false;
786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787
Steve Antonb1c1de12017-12-21 15:14:30 -0800788 const AudioContentDescription* audio = content->as_audio();
789
jbauch5869f502017-06-29 12:31:36 -0700790 RtpHeaderExtensions rtp_header_extensions =
791 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
792
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700793 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700794 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
795 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -0700796 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700797
798 bool parameters_applied = media_channel()->SetSendParameters(send_params);
799 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700800 SafeSetError("Failed to set remote audio description send parameters.",
801 error_desc);
802 return false;
803 }
804 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700806 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
807 // and only give it to the media channel once we have a local
808 // description too (without a local description, we won't be able to
809 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800810 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700811 SafeSetError("Failed to set remote audio description streams.", error_desc);
812 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813 }
814
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700815 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700816 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700817 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818}
819
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200820VideoChannel::VideoChannel(rtc::Thread* worker_thread,
821 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800822 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800823 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700825 bool srtp_required,
826 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200827 : BaseChannel(worker_thread,
828 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800829 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800830 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700831 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700832 srtp_required,
833 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800836 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837 // this can't be done in the base class, since it calls a virtual
838 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700839 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840}
841
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700842void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843 // Send outgoing data if we're the active call, we have the remote content,
844 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700845 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100847 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 // TODO(gangji): Report error back to server.
849 }
850
Mirko Bonadei675513b2017-11-09 11:09:25 +0100851 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852}
853
stefanf79ade12017-06-02 06:44:03 -0700854void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
855 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
856 media_channel(), bwe_info));
857}
858
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800860 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000861 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100862 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800863 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100864 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865
Steve Antonb1c1de12017-12-21 15:14:30 -0800866 RTC_DCHECK(content);
867 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000868 SafeSetError("Can't find video content in local description.", error_desc);
869 return false;
870 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871
Steve Antonb1c1de12017-12-21 15:14:30 -0800872 const VideoContentDescription* video = content->as_video();
873
jbauch5869f502017-06-29 12:31:36 -0700874 RtpHeaderExtensions rtp_header_extensions =
875 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
876
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700877 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -0700878 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700879 if (!media_channel()->SetRecvParameters(recv_params)) {
880 SafeSetError("Failed to set local video description recv parameters.",
881 error_desc);
882 return false;
883 }
884 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -0700885 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700886 }
887 last_recv_params_ = recv_params;
888
889 // TODO(pthatcher): Move local streams into VideoSendParameters, and
890 // only give it to the media channel once we have a remote
891 // description too (without a remote description, we won't be able
892 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800893 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700894 SafeSetError("Failed to set local video description streams.", error_desc);
895 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 }
897
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700898 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700899 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700900 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901}
902
903bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800904 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000905 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100906 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -0800907 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100908 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909
Steve Antonb1c1de12017-12-21 15:14:30 -0800910 RTC_DCHECK(content);
911 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000912 SafeSetError("Can't find video content in remote description.", error_desc);
913 return false;
914 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
Steve Antonb1c1de12017-12-21 15:14:30 -0800916 const VideoContentDescription* video = content->as_video();
917
jbauch5869f502017-06-29 12:31:36 -0700918 RtpHeaderExtensions rtp_header_extensions =
919 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
920
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700921 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -0700922 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
923 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700924 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -0800925 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700926 }
Steve Antonbb50ce52018-03-26 10:24:32 -0700927 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -0700928
929 bool parameters_applied = media_channel()->SetSendParameters(send_params);
930
931 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700932 SafeSetError("Failed to set remote video description send parameters.",
933 error_desc);
934 return false;
935 }
936 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700938 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
939 // and only give it to the media channel once we have a local
940 // description too (without a local description, we won't be able to
941 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -0800942 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700943 SafeSetError("Failed to set remote video description streams.", error_desc);
944 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700946 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700947 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700948 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
deadbeef953c2ce2017-01-09 14:53:41 -0800951RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
952 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800953 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800954 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -0800955 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700956 bool srtp_required,
957 rtc::CryptoOptions crypto_options)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200958 : BaseChannel(worker_thread,
959 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -0800960 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800961 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -0700962 content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700963 srtp_required,
964 crypto_options) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
deadbeef953c2ce2017-01-09 14:53:41 -0800966RtpDataChannel::~RtpDataChannel() {
967 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 // this can't be done in the base class, since it calls a virtual
969 DisableMedia_w();
Zhi Huang0ffe03d2018-03-30 13:17:42 -0700970 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971}
972
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800973void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
974 BaseChannel::Init_w(rtp_transport);
975 media_channel()->SignalDataReceived.connect(this,
976 &RtpDataChannel::OnDataReceived);
977 media_channel()->SignalReadyToSend.connect(
978 this, &RtpDataChannel::OnDataChannelReadyToSend);
979}
980
deadbeef953c2ce2017-01-09 14:53:41 -0800981bool RtpDataChannel::SendData(const SendDataParams& params,
982 const rtc::CopyOnWriteBuffer& payload,
983 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -0700984 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700985 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
986 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987}
988
deadbeef953c2ce2017-01-09 14:53:41 -0800989bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990 const DataContentDescription* content,
991 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
993 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -0800994 // It's been set before, but doesn't match. That's bad.
995 if (is_sctp) {
996 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
997 error_desc);
998 return false;
999 }
1000 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001}
1002
deadbeef953c2ce2017-01-09 14:53:41 -08001003bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001004 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001005 std::string* error_desc) {
1006 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001007 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001008 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009
Steve Antonb1c1de12017-12-21 15:14:30 -08001010 RTC_DCHECK(content);
1011 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001012 SafeSetError("Can't find data content in local description.", error_desc);
1013 return false;
1014 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015
Steve Antonb1c1de12017-12-21 15:14:30 -08001016 const DataContentDescription* data = content->as_data();
1017
deadbeef953c2ce2017-01-09 14:53:41 -08001018 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019 return false;
1020 }
1021
jbauch5869f502017-06-29 12:31:36 -07001022 RtpHeaderExtensions rtp_header_extensions =
1023 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1024
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001025 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001026 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001027 if (!media_channel()->SetRecvParameters(recv_params)) {
1028 SafeSetError("Failed to set remote data description recv parameters.",
1029 error_desc);
1030 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031 }
deadbeef953c2ce2017-01-09 14:53:41 -08001032 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001033 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001034 }
1035 last_recv_params_ = recv_params;
1036
1037 // TODO(pthatcher): Move local streams into DataSendParameters, and
1038 // only give it to the media channel once we have a remote
1039 // description too (without a remote description, we won't be able
1040 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001041 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001042 SafeSetError("Failed to set local data description streams.", error_desc);
1043 return false;
1044 }
1045
1046 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001047 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001048 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001049}
1050
deadbeef953c2ce2017-01-09 14:53:41 -08001051bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001052 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001053 std::string* error_desc) {
1054 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001055 RTC_DCHECK_RUN_ON(worker_thread());
1056 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057
Steve Antonb1c1de12017-12-21 15:14:30 -08001058 RTC_DCHECK(content);
1059 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001060 SafeSetError("Can't find data content in remote description.", error_desc);
1061 return false;
1062 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063
Steve Antonb1c1de12017-12-21 15:14:30 -08001064 const DataContentDescription* data = content->as_data();
1065
Zhi Huang801b8682017-11-15 11:36:43 -08001066 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1067 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001068 return true;
1069 }
1070
deadbeef953c2ce2017-01-09 14:53:41 -08001071 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001072 return false;
1073 }
1074
jbauch5869f502017-06-29 12:31:36 -07001075 RtpHeaderExtensions rtp_header_extensions =
1076 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1077
Mirko Bonadei675513b2017-11-09 11:09:25 +01001078 RTC_LOG(LS_INFO) << "Setting remote data description";
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001079 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001080 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
1081 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001082 if (!media_channel()->SetSendParameters(send_params)) {
1083 SafeSetError("Failed to set remote data description send parameters.",
1084 error_desc);
1085 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001086 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001087 last_send_params_ = send_params;
1088
1089 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1090 // and only give it to the media channel once we have a local
1091 // description too (without a local description, we won't be able to
1092 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001093 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001094 SafeSetError("Failed to set remote data description streams.",
1095 error_desc);
1096 return false;
1097 }
1098
1099 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001100 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001101 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001102}
1103
deadbeef953c2ce2017-01-09 14:53:41 -08001104void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001105 // Render incoming data if we're the active call, and we have the local
1106 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001107 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001108 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001109 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110 }
1111
1112 // Send outgoing data if we're the active call, we have the remote content,
1113 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001114 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001115 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001116 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001117 }
1118
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001119 // Trigger SignalReadyToSendData asynchronously.
1120 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001121
Mirko Bonadei675513b2017-11-09 11:09:25 +01001122 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001123}
1124
deadbeef953c2ce2017-01-09 14:53:41 -08001125void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126 switch (pmsg->message_id) {
1127 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001128 DataChannelReadyToSendMessageData* data =
1129 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001130 ready_to_send_data_ = data->data();
1131 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001132 delete data;
1133 break;
1134 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001135 case MSG_DATARECEIVED: {
1136 DataReceivedMessageData* data =
1137 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001138 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139 delete data;
1140 break;
1141 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142 default:
1143 BaseChannel::OnMessage(pmsg);
1144 break;
1145 }
1146}
1147
deadbeef953c2ce2017-01-09 14:53:41 -08001148void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1149 const char* data,
1150 size_t len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001151 DataReceivedMessageData* msg = new DataReceivedMessageData(
1152 params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001153 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001154}
1155
deadbeef953c2ce2017-01-09 14:53:41 -08001156void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001157 // This is usded for congestion control to indicate that the stream is ready
1158 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1159 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001160 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001161 new DataChannelReadyToSendMessageData(writable));
1162}
1163
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164} // namespace cricket