1 /*
2 * libjingle
3 * Copyright 2004--2007, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "talk/session/phone/channel.h"
29
30 #include "talk/base/buffer.h"
31 #include "talk/base/byteorder.h"
32 #include "talk/base/common.h"
33 #include "talk/base/logging.h"
34 #include "talk/p2p/base/transportchannel.h"
35 #include "talk/session/phone/channelmanager.h"
36 #include "talk/session/phone/mediamessages.h"
37 #include "talk/session/phone/mediasessionclient.h"
38 #include "talk/session/phone/rtcpmuxfilter.h"
39 #include "talk/session/phone/rtputils.h"
40
41 namespace cricket {
42
43 enum {
44 MSG_ENABLE = 1,
45 MSG_DISABLE = 2,
46 MSG_MUTE = 3,
47 MSG_UNMUTE = 4,
48 MSG_SETREMOTECONTENT = 5,
49 MSG_SETLOCALCONTENT = 6,
50 MSG_EARLYMEDIATIMEOUT = 8,
51 MSG_PRESSDTMF = 9,
52 MSG_SETRENDERER = 10,
53 MSG_ADDRECVSTREAM = 11,
54 MSG_REMOVERECVSTREAM = 12,
55 MSG_SETRINGBACKTONE = 13,
56 MSG_PLAYRINGBACKTONE = 14,
57 MSG_SETMAXSENDBANDWIDTH = 15,
58 MSG_ADDSCREENCAST = 16,
59 MSG_REMOVESCREENCAST = 17,
60 // Removed MSG_SETRTCPCNAME = 18. It is no longer used.
61 MSG_SENDINTRAFRAME = 19,
62 MSG_REQUESTINTRAFRAME = 20,
63 MSG_SCREENCASTWINDOWEVENT = 21,
64 MSG_RTPPACKET = 22,
65 MSG_RTCPPACKET = 23,
66 MSG_CHANNEL_ERROR = 24,
67 MSG_SETCHANNELOPTIONS = 25,
68 MSG_SCALEVOLUME = 26,
69 MSG_HANDLEVIEWREQUEST = 27,
70 MSG_SENDDATA = 28,
71 MSG_DATARECEIVED = 29
72 };
73
74 struct SetContentData : public talk_base::MessageData {
SetContentDatacricket::SetContentData75 SetContentData(const MediaContentDescription* content, ContentAction action)
76 : content(content),
77 action(action),
78 result(false) {
79 }
80 const MediaContentDescription* content;
81 ContentAction action;
82 bool result;
83 };
84
85 struct SetBandwidthData : public talk_base::MessageData {
SetBandwidthDatacricket::SetBandwidthData86 explicit SetBandwidthData(int value) : value(value), result(false) {}
87 int value;
88 bool result;
89 };
90
91 struct SetRingbackToneMessageData : public talk_base::MessageData {
SetRingbackToneMessageDatacricket::SetRingbackToneMessageData92 SetRingbackToneMessageData(const void* b, int l)
93 : buf(b),
94 len(l),
95 result(false) {
96 }
97 const void* buf;
98 int len;
99 bool result;
100 };
101
102 struct PlayRingbackToneMessageData : public talk_base::MessageData {
PlayRingbackToneMessageDatacricket::PlayRingbackToneMessageData103 PlayRingbackToneMessageData(uint32 s, bool p, bool l)
104 : ssrc(s),
105 play(p),
106 loop(l),
107 result(false) {
108 }
109 uint32 ssrc;
110 bool play;
111 bool loop;
112 bool result;
113 };
114 struct DtmfMessageData : public talk_base::MessageData {
DtmfMessageDatacricket::DtmfMessageData115 DtmfMessageData(int d, bool p)
116 : digit(d),
117 playout(p),
118 result(false) {
119 }
120 int digit;
121 bool playout;
122 bool result;
123 };
124 struct ScaleVolumeMessageData : public talk_base::MessageData {
ScaleVolumeMessageDatacricket::ScaleVolumeMessageData125 ScaleVolumeMessageData(uint32 s, double l, double r)
126 : ssrc(s),
127 left(l),
128 right(r),
129 result(false) {
130 }
131 uint32 ssrc;
132 double left;
133 double right;
134 bool result;
135 };
136
137 struct PacketMessageData : public talk_base::MessageData {
138 talk_base::Buffer packet;
139 };
140
141 struct RenderMessageData : public talk_base::MessageData {
RenderMessageDatacricket::RenderMessageData142 RenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
143 uint32 ssrc;
144 VideoRenderer* renderer;
145 };
146
147 struct ScreencastMessageData : public talk_base::MessageData {
ScreencastMessageDatacricket::ScreencastMessageData148 ScreencastMessageData(uint32 s, const ScreencastId& id, int f)
149 : ssrc(s),
150 window_id(id),
151 fps(f) {
152 }
153 uint32 ssrc;
154 ScreencastId window_id;
155 int fps;
156 };
157
158 struct ScreencastEventMessageData : public talk_base::MessageData {
ScreencastEventMessageDatacricket::ScreencastEventMessageData159 ScreencastEventMessageData(uint32 s, talk_base::WindowEvent we)
160 : ssrc(s),
161 event(we) {
162 }
163 uint32 ssrc;
164 talk_base::WindowEvent event;
165 };
166
167 struct ViewRequestMessageData : public talk_base::MessageData {
ViewRequestMessageDatacricket::ViewRequestMessageData168 explicit ViewRequestMessageData(const ViewRequest& r)
169 : request(r),
170 result(false) {
171 }
172 ViewRequest request;
173 bool result;
174 };
175
176 struct VoiceChannelErrorMessageData : public talk_base::MessageData {
VoiceChannelErrorMessageDatacricket::VoiceChannelErrorMessageData177 VoiceChannelErrorMessageData(uint32 in_ssrc,
178 VoiceMediaChannel::Error in_error)
179 : ssrc(in_ssrc),
180 error(in_error) {
181 }
182 uint32 ssrc;
183 VoiceMediaChannel::Error error;
184 };
185
186 struct VideoChannelErrorMessageData : public talk_base::MessageData {
VideoChannelErrorMessageDatacricket::VideoChannelErrorMessageData187 VideoChannelErrorMessageData(uint32 in_ssrc,
188 VideoMediaChannel::Error in_error)
189 : ssrc(in_ssrc),
190 error(in_error) {
191 }
192 uint32 ssrc;
193 VideoMediaChannel::Error error;
194 };
195
196 struct DataChannelErrorMessageData : public talk_base::MessageData {
DataChannelErrorMessageDatacricket::DataChannelErrorMessageData197 DataChannelErrorMessageData(uint32 in_ssrc,
198 DataMediaChannel::Error in_error)
199 : ssrc(in_ssrc),
200 error(in_error) {}
201 uint32 ssrc;
202 DataMediaChannel::Error error;
203 };
204
205 struct SsrcMessageData : public talk_base::MessageData {
SsrcMessageDatacricket::SsrcMessageData206 explicit SsrcMessageData(uint32 ssrc) : ssrc(ssrc), result(false) {}
207 uint32 ssrc;
208 bool result;
209 };
210
211 struct StreamMessageData : public talk_base::MessageData {
StreamMessageDatacricket::StreamMessageData212 explicit StreamMessageData(const StreamParams& in_sp)
213 : sp(in_sp),
214 result(false) {
215 }
216 StreamParams sp;
217 bool result;
218 };
219
220 struct ChannelOptionsMessageData : public talk_base::MessageData {
ChannelOptionsMessageDatacricket::ChannelOptionsMessageData221 explicit ChannelOptionsMessageData(int in_options) : options(in_options) {}
222 int options;
223 };
224
PacketType(bool rtcp)225 static const char* PacketType(bool rtcp) {
226 return (!rtcp) ? "RTP" : "RTCP";
227 }
228
ValidPacket(bool rtcp,const talk_base::Buffer * packet)229 static bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) {
230 // Check the packet size. We could check the header too if needed.
231 return (packet &&
232 packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) &&
233 packet->length() <= kMaxRtpPacketLen);
234 }
235
BaseChannel(talk_base::Thread * thread,MediaEngineInterface * media_engine,MediaChannel * media_channel,BaseSession * session,const std::string & content_name,bool rtcp)236 BaseChannel::BaseChannel(talk_base::Thread* thread,
237 MediaEngineInterface* media_engine,
238 MediaChannel* media_channel, BaseSession* session,
239 const std::string& content_name, bool rtcp)
240 : worker_thread_(thread),
241 media_engine_(media_engine),
242 session_(session),
243 media_channel_(media_channel),
244 content_name_(content_name),
245 rtcp_(rtcp),
246 transport_channel_(NULL),
247 rtcp_transport_channel_(NULL),
248 enabled_(false),
249 writable_(false),
250 was_ever_writable_(false),
251 has_local_content_(false),
252 has_remote_content_(false),
253 muted_(false) {
254 ASSERT(worker_thread_ == talk_base::Thread::Current());
255 LOG(LS_INFO) << "Created channel for " << content_name;
256 }
257
~BaseChannel()258 BaseChannel::~BaseChannel() {
259 ASSERT(worker_thread_ == talk_base::Thread::Current());
260 StopConnectionMonitor();
261 FlushRtcpMessages(); // Send any outstanding RTCP packets.
262 Clear(); // eats any outstanding messages or packets
263 // We must destroy the media channel before the transport channel, otherwise
264 // the media channel may try to send on the dead transport channel. NULLing
265 // is not an effective strategy since the sends will come on another thread.
266 delete media_channel_;
267 set_rtcp_transport_channel(NULL);
268 if (transport_channel_ != NULL)
269 session_->DestroyChannel(content_name_, transport_channel_->name());
270 LOG(LS_INFO) << "Destroyed channel";
271 }
272
Init(TransportChannel * transport_channel,TransportChannel * rtcp_transport_channel)273 bool BaseChannel::Init(TransportChannel* transport_channel,
274 TransportChannel* rtcp_transport_channel) {
275 if (transport_channel == NULL) {
276 return false;
277 }
278 if (rtcp() && rtcp_transport_channel == NULL) {
279 return false;
280 }
281 transport_channel_ = transport_channel;
282 media_channel_->SetInterface(this);
283 transport_channel_->SignalWritableState.connect(
284 this, &BaseChannel::OnWritableState);
285 transport_channel_->SignalReadPacket.connect(
286 this, &BaseChannel::OnChannelRead);
287
288 session_->SignalState.connect(this, &BaseChannel::OnSessionState);
289
290 OnSessionState(session(), session()->state());
291 set_rtcp_transport_channel(rtcp_transport_channel);
292 return true;
293 }
294
295 // Can be called from thread other than worker thread
Enable(bool enable)296 bool BaseChannel::Enable(bool enable) {
297 Send(enable ? MSG_ENABLE : MSG_DISABLE);
298 return true;
299 }
300
301 // Can be called from thread other than worker thread
Mute(bool mute)302 bool BaseChannel::Mute(bool mute) {
303 Clear(MSG_UNMUTE); // Clear any penging auto-unmutes.
304 Send(mute ? MSG_MUTE : MSG_UNMUTE);
305 return true;
306 }
307
AddRecvStream(const StreamParams & sp)308 bool BaseChannel::AddRecvStream(const StreamParams& sp) {
309 StreamMessageData data(sp);
310 Send(MSG_ADDRECVSTREAM, &data);
311 return data.result;
312 }
313
RemoveRecvStream(uint32 ssrc)314 bool BaseChannel::RemoveRecvStream(uint32 ssrc) {
315 SsrcMessageData data(ssrc);
316 Send(MSG_REMOVERECVSTREAM, &data);
317 return data.result;
318 }
319
SetLocalContent(const MediaContentDescription * content,ContentAction action)320 bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
321 ContentAction action) {
322 SetContentData data(content, action);
323 Send(MSG_SETLOCALCONTENT, &data);
324 return data.result;
325 }
326
SetRemoteContent(const MediaContentDescription * content,ContentAction action)327 bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
328 ContentAction action) {
329 SetContentData data(content, action);
330 Send(MSG_SETREMOTECONTENT, &data);
331 return data.result;
332 }
333
SetMaxSendBandwidth(int max_bandwidth)334 bool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) {
335 SetBandwidthData data(max_bandwidth);
336 Send(MSG_SETMAXSENDBANDWIDTH, &data);
337 return data.result;
338 }
339
StartConnectionMonitor(int cms)340 void BaseChannel::StartConnectionMonitor(int cms) {
341 socket_monitor_.reset(new SocketMonitor(transport_channel_,
342 worker_thread(),
343 talk_base::Thread::Current()));
344 socket_monitor_->SignalUpdate.connect(
345 this, &BaseChannel::OnConnectionMonitorUpdate);
346 socket_monitor_->Start(cms);
347 }
348
StopConnectionMonitor()349 void BaseChannel::StopConnectionMonitor() {
350 if (socket_monitor_.get()) {
351 socket_monitor_->Stop();
352 socket_monitor_.reset();
353 }
354 }
355
set_rtcp_transport_channel(TransportChannel * channel)356 void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) {
357 if (rtcp_transport_channel_ != channel) {
358 if (rtcp_transport_channel_) {
359 session_->DestroyChannel(content_name_, rtcp_transport_channel_->name());
360 }
361 rtcp_transport_channel_ = channel;
362 if (rtcp_transport_channel_) {
363 rtcp_transport_channel_->SignalWritableState.connect(
364 this, &BaseChannel::OnWritableState);
365 rtcp_transport_channel_->SignalReadPacket.connect(
366 this, &BaseChannel::OnChannelRead);
367 }
368 }
369 }
370
SendPacket(talk_base::Buffer * packet)371 bool BaseChannel::SendPacket(talk_base::Buffer* packet) {
372 return SendPacket(false, packet);
373 }
374
SendRtcp(talk_base::Buffer * packet)375 bool BaseChannel::SendRtcp(talk_base::Buffer* packet) {
376 return SendPacket(true, packet);
377 }
378
SetOption(SocketType type,talk_base::Socket::Option opt,int value)379 int BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt,
380 int value) {
381 switch (type) {
382 case ST_RTP: return transport_channel_->SetOption(opt, value);
383 case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value);
384 default: return -1;
385 }
386 }
387
OnWritableState(TransportChannel * channel)388 void BaseChannel::OnWritableState(TransportChannel* channel) {
389 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
390 if (transport_channel_->writable()
391 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) {
392 ChannelWritable_w();
393 } else {
394 ChannelNotWritable_w();
395 }
396 }
397
OnChannelRead(TransportChannel * channel,const char * data,size_t len)398 void BaseChannel::OnChannelRead(TransportChannel* channel,
399 const char* data, size_t len) {
400 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
401 ASSERT(worker_thread_ == talk_base::Thread::Current());
402
403 // When using RTCP multiplexing we might get RTCP packets on the RTP
404 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP.
405 bool rtcp = PacketIsRtcp(channel, data, len);
406 talk_base::Buffer packet(data, len);
407 HandlePacket(rtcp, &packet);
408 }
409
PacketIsRtcp(const TransportChannel * channel,const char * data,size_t len)410 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel,
411 const char* data, size_t len) {
412 return (channel == rtcp_transport_channel_ ||
413 rtcp_mux_filter_.DemuxRtcp(data, len));
414 }
415
SendPacket(bool rtcp,talk_base::Buffer * packet)416 bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet) {
417 // Ensure we have a path capable of sending packets.
418 if (!writable_) {
419 return false;
420 }
421
422 // SendPacket gets called from MediaEngine, typically on an encoder thread.
423 // If the thread is not our worker thread, we will post to our worker
424 // so that the real work happens on our worker. This avoids us having to
425 // synchronize access to all the pieces of the send path, including
426 // SRTP and the inner workings of the transport channels.
427 // The only downside is that we can't return a proper failure code if
428 // needed. Since UDP is unreliable anyway, this should be a non-issue.
429 if (talk_base::Thread::Current() != worker_thread_) {
430 // Avoid a copy by transferring the ownership of the packet data.
431 int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET;
432 PacketMessageData* data = new PacketMessageData;
433 packet->TransferTo(&data->packet);
434 worker_thread_->Post(this, message_id, data);
435 return true;
436 }
437
438 // Now that we are on the correct thread, ensure we have a place to send this
439 // packet before doing anything. (We might get RTCP packets that we don't
440 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
441 // transport.
442 TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ?
443 transport_channel_ : rtcp_transport_channel_;
444 if (!channel || !channel->writable()) {
445 return false;
446 }
447
448 // Protect ourselves against crazy data.
449 if (!ValidPacket(rtcp, packet)) {
450 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
451 << PacketType(rtcp) << " packet: wrong size="
452 << packet->length();
453 return false;
454 }
455
456 // Signal to the media sink before protecting the packet.
457 {
458 talk_base::CritScope cs(&signal_send_packet_cs_);
459 SignalSendPacketPreCrypto(packet->data(), packet->length(), rtcp);
460 }
461
462 // Protect if needed.
463 if (srtp_filter_.IsActive()) {
464 bool res;
465 char* data = packet->data();
466 int len = packet->length();
467 if (!rtcp) {
468 res = srtp_filter_.ProtectRtp(data, len, packet->capacity(), &len);
469 if (!res) {
470 int seq_num = -1;
471 uint32 ssrc = 0;
472 GetRtpSeqNum(data, len, &seq_num);
473 GetRtpSsrc(data, len, &ssrc);
474 LOG(LS_ERROR) << "Failed to protect " << content_name_
475 << " RTP packet: size=" << len
476 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
477 return false;
478 }
479 } else {
480 res = srtp_filter_.ProtectRtcp(data, len, packet->capacity(), &len);
481 if (!res) {
482 int type = -1;
483 GetRtcpType(data, len, &type);
484 LOG(LS_ERROR) << "Failed to protect " << content_name_
485 << " RTCP packet: size=" << len << ", type=" << type;
486 return false;
487 }
488 }
489
490 // Update the length of the packet now that we've added the auth tag.
491 packet->SetLength(len);
492 }
493
494 // Signal to the media sink after protecting the packet.
495 {
496 talk_base::CritScope cs(&signal_send_packet_cs_);
497 SignalSendPacketPostCrypto(packet->data(), packet->length(), rtcp);
498 }
499
500 // Bon voyage.
501 return (channel->SendPacket(packet->data(), packet->length())
502 == static_cast<int>(packet->length()));
503 }
504
HandlePacket(bool rtcp,talk_base::Buffer * packet)505 void BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) {
506 // Protect ourselvs against crazy data.
507 if (!ValidPacket(rtcp, packet)) {
508 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " "
509 << PacketType(rtcp) << " packet: wrong size="
510 << packet->length();
511 return;
512 }
513
514 // If this channel is suppose to handle RTP data, that is determined by
515 // checking against ssrc filter. This is necessary to do it here to avoid
516 // double decryption.
517 if (ssrc_filter_.IsActive() &&
518 !ssrc_filter_.DemuxPacket(packet->data(), packet->length(), rtcp)) {
519 return;
520 }
521
522 // Signal to the media sink before unprotecting the packet.
523 {
524 talk_base::CritScope cs(&signal_recv_packet_cs_);
525 SignalRecvPacketPostCrypto(packet->data(), packet->length(), rtcp);
526 }
527
528 // Unprotect the packet, if needed.
529 if (srtp_filter_.IsActive()) {
530 char* data = packet->data();
531 int len = packet->length();
532 bool res;
533 if (!rtcp) {
534 res = srtp_filter_.UnprotectRtp(data, len, &len);
535 if (!res) {
536 int seq_num = -1;
537 uint32 ssrc = 0;
538 GetRtpSeqNum(data, len, &seq_num);
539 GetRtpSsrc(data, len, &ssrc);
540 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
541 << " RTP packet: size=" << len
542 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
543 return;
544 }
545 } else {
546 res = srtp_filter_.UnprotectRtcp(data, len, &len);
547 if (!res) {
548 int type = -1;
549 GetRtcpType(data, len, &type);
550 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
551 << " RTCP packet: size=" << len << ", type=" << type;
552 return;
553 }
554 }
555
556 packet->SetLength(len);
557 }
558
559 // Signal to the media sink after unprotecting the packet.
560 {
561 talk_base::CritScope cs(&signal_recv_packet_cs_);
562 SignalRecvPacketPreCrypto(packet->data(), packet->length(), rtcp);
563 }
564
565 // Push it down to the media channel.
566 if (!rtcp) {
567 media_channel_->OnPacketReceived(packet);
568 } else {
569 media_channel_->OnRtcpReceived(packet);
570 }
571 }
572
OnSessionState(BaseSession * session,BaseSession::State state)573 void BaseChannel::OnSessionState(BaseSession* session,
574 BaseSession::State state) {
575 const MediaContentDescription* content = NULL;
576 switch (state) {
577 case Session::STATE_SENTINITIATE:
578 content = GetFirstContent(session->local_description());
579 if (content && !SetLocalContent(content, CA_OFFER)) {
580 LOG(LS_ERROR) << "Failure in SetLocalContent with CA_OFFER";
581 session->SetError(BaseSession::ERROR_CONTENT);
582 }
583 break;
584 case Session::STATE_SENTACCEPT:
585 content = GetFirstContent(session->local_description());
586 if (content && !SetLocalContent(content, CA_ANSWER)) {
587 LOG(LS_ERROR) << "Failure in SetLocalContent with CA_ANSWER";
588 session->SetError(BaseSession::ERROR_CONTENT);
589 }
590 break;
591 case Session::STATE_RECEIVEDINITIATE:
592 content = GetFirstContent(session->remote_description());
593 if (content && !SetRemoteContent(content, CA_OFFER)) {
594 LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_OFFER";
595 session->SetError(BaseSession::ERROR_CONTENT);
596 }
597 break;
598 case Session::STATE_RECEIVEDACCEPT:
599 content = GetFirstContent(session->remote_description());
600 if (content && !SetRemoteContent(content, CA_ANSWER)) {
601 LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_ANSWER";
602 session->SetError(BaseSession::ERROR_CONTENT);
603 }
604 break;
605 default:
606 break;
607 }
608 }
609
SetChannelOptions(int options)610 void BaseChannel::SetChannelOptions(int options) {
611 ChannelOptionsMessageData data(options);
612 Send(MSG_SETCHANNELOPTIONS, &data);
613 }
614
EnableMedia_w()615 void BaseChannel::EnableMedia_w() {
616 ASSERT(worker_thread_ == talk_base::Thread::Current());
617 if (enabled_)
618 return;
619
620 LOG(LS_INFO) << "Channel enabled";
621 enabled_ = true;
622 ChangeState();
623 }
624
DisableMedia_w()625 void BaseChannel::DisableMedia_w() {
626 ASSERT(worker_thread_ == talk_base::Thread::Current());
627 if (!enabled_)
628 return;
629
630 LOG(LS_INFO) << "Channel disabled";
631 enabled_ = false;
632 ChangeState();
633 }
634
MuteMedia_w()635 void BaseChannel::MuteMedia_w() {
636 ASSERT(worker_thread_ == talk_base::Thread::Current());
637 if (muted_)
638 return;
639
640 if (media_channel()->Mute(true)) {
641 LOG(LS_INFO) << "Channel muted";
642 muted_ = true;
643 }
644 }
645
UnmuteMedia_w()646 void BaseChannel::UnmuteMedia_w() {
647 ASSERT(worker_thread_ == talk_base::Thread::Current());
648 if (!muted_)
649 return;
650
651 if (media_channel()->Mute(false)) {
652 LOG(LS_INFO) << "Channel unmuted";
653 muted_ = false;
654 }
655 }
656
ChannelWritable_w()657 void BaseChannel::ChannelWritable_w() {
658 ASSERT(worker_thread_ == talk_base::Thread::Current());
659 if (writable_)
660 return;
661 LOG(LS_INFO) << "Channel socket writable ("
662 << transport_channel_->name().c_str() << ")"
663 << (was_ever_writable_ ? "" : " for the first time");
664 was_ever_writable_ = true;
665 writable_ = true;
666 ChangeState();
667 }
668
ChannelNotWritable_w()669 void BaseChannel::ChannelNotWritable_w() {
670 ASSERT(worker_thread_ == talk_base::Thread::Current());
671 if (!writable_)
672 return;
673
674 LOG(LS_INFO) << "Channel socket not writable ("
675 << transport_channel_->name().c_str() << ")";
676 writable_ = false;
677 ChangeState();
678 }
679
680 // Sets the maximum video bandwidth for automatic bandwidth adjustment.
SetMaxSendBandwidth_w(int max_bandwidth)681 bool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) {
682 return media_channel()->SetSendBandwidth(true, max_bandwidth);
683 }
684
SetSrtp_w(const std::vector<CryptoParams> & cryptos,ContentAction action,ContentSource src)685 bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos,
686 ContentAction action, ContentSource src) {
687 bool ret;
688 if (action == CA_OFFER) {
689 ret = srtp_filter_.SetOffer(cryptos, src);
690 } else if (action == CA_ANSWER) {
691 ret = srtp_filter_.SetAnswer(cryptos, src);
692 } else {
693 // CA_UPDATE, no crypto params.
694 ret = true;
695 }
696 return ret;
697 }
698
SetRtcpMux_w(bool enable,ContentAction action,ContentSource src)699 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action,
700 ContentSource src) {
701 bool ret;
702 if (action == CA_OFFER) {
703 ret = rtcp_mux_filter_.SetOffer(enable, src);
704 } else if (action == CA_ANSWER) {
705 ret = rtcp_mux_filter_.SetAnswer(enable, src);
706 if (ret && rtcp_mux_filter_.IsActive()) {
707 // We activated RTCP mux, close down the RTCP transport.
708 set_rtcp_transport_channel(NULL);
709 // If the RTP transport is already writable, then so are we.
710 if (transport_channel_->writable()) {
711 ChannelWritable_w();
712 }
713 }
714 } else {
715 // CA_UPDATE, no RTCP mux info.
716 ret = true;
717 }
718 return ret;
719 }
720
SetChannelOptions_w(int options)721 void BaseChannel::SetChannelOptions_w(int options) {
722 media_channel()->SetOptions(options);
723 }
724
AddRecvStream_w(const StreamParams & sp)725 bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
726 ASSERT(worker_thread() == talk_base::Thread::Current());
727 if (!media_channel()->AddRecvStream(sp))
728 return false;
729
730 return ssrc_filter_.AddStream(sp);
731 }
732
RemoveRecvStream_w(uint32 ssrc)733 bool BaseChannel::RemoveRecvStream_w(uint32 ssrc) {
734 ASSERT(worker_thread() == talk_base::Thread::Current());
735 ssrc_filter_.RemoveStream(ssrc);
736 return media_channel()->RemoveRecvStream(ssrc);
737 }
738
UpdateLocalStreams_w(const std::vector<StreamParams> & streams,ContentAction action)739 bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
740 ContentAction action) {
741 if (!VERIFY(action == CA_OFFER || action == CA_ANSWER || action == CA_UPDATE))
742 return false;
743
744 // If this is an update, streams only contain streams that have changed.
745 if (action == CA_UPDATE) {
746 for (StreamParamsVec::const_iterator it = streams.begin();
747 it != streams.end(); ++it) {
748 StreamParams existing_stream;
749 bool stream_exist = GetStreamByNickAndName(local_streams_, it->nick,
750 it->name, &existing_stream);
751 if (!stream_exist && it->has_ssrcs()) {
752 if (media_channel()->AddSendStream(*it)) {
753 local_streams_.push_back(*it);
754 LOG(LS_INFO) << "Add send stream ssrc: " << it->first_ssrc();
755 } else {
756 LOG(LS_INFO) << "Failed to add send stream ssrc: "
757 << it->first_ssrc();
758 return false;
759 }
760 } else if (stream_exist && !it->has_ssrcs()) {
761 if (!media_channel()->RemoveSendStream(existing_stream.first_ssrc())) {
762 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
763 << it->first_ssrc() << ".";
764 return false;
765 }
766 RemoveStreamBySsrc(&local_streams_, existing_stream.first_ssrc());
767 } else {
768 LOG(LS_WARNING) << "Ignore unsupported stream update";
769 }
770 }
771 return true;
772 }
773 // Else streams are all the streams we want to send.
774
775 // Check for streams that have been removed.
776 bool ret = true;
777 for (StreamParamsVec::const_iterator it = local_streams_.begin();
778 it != local_streams_.end(); ++it) {
779 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
780 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
781 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
782 << it->first_ssrc() << ".";
783 ret = false;
784 }
785 }
786 }
787 // Check for new streams.
788 for (StreamParamsVec::const_iterator it = streams.begin();
789 it != streams.end(); ++it) {
790 if (!GetStreamBySsrc(local_streams_, it->first_ssrc(), NULL)) {
791 if (media_channel()->AddSendStream(*it)) {
792 LOG(LS_INFO) << "Add send ssrc: " << it->ssrcs[0];
793 } else {
794 LOG(LS_INFO) << "Failed to add send stream ssrc: " << it->first_ssrc();
795 ret = false;
796 }
797 }
798 }
799 local_streams_ = streams;
800 return ret;
801 }
802
UpdateRemoteStreams_w(const std::vector<StreamParams> & streams,ContentAction action)803 bool BaseChannel::UpdateRemoteStreams_w(
804 const std::vector<StreamParams>& streams,
805 ContentAction action) {
806 // If this is an update, streams only contain streams that have changed.
807 if (action == CA_UPDATE) {
808 for (StreamParamsVec::const_iterator it = streams.begin();
809 it != streams.end(); ++it) {
810 StreamParams existing_stream;
811 bool stream_exists = GetStreamByNickAndName(remote_streams_, it->nick,
812 it->name, &existing_stream);
813 if (!stream_exists && it->has_ssrcs()) {
814 if (AddRecvStream_w(*it)) {
815 remote_streams_.push_back(*it);
816 LOG(LS_INFO) << "Add remote stream ssrc: " << it->first_ssrc();
817 } else {
818 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
819 << it->first_ssrc();
820 return false;
821 }
822 } else if (stream_exists && !it->has_ssrcs()) {
823 if (!RemoveRecvStream_w(existing_stream.first_ssrc())) {
824 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
825 << it->first_ssrc() << ".";
826 return false;
827 }
828 RemoveStreamBySsrc(&remote_streams_, existing_stream.first_ssrc());
829 } else {
830 LOG(LS_WARNING) << "Ignore unsupported stream update"
831 << " stream name = " << it->name
832 << " stream exists? " << stream_exists
833 << " has ssrcs? " << it->has_ssrcs();
834 }
835 }
836 return true;
837 }
838 // Else streams are all the streams we want to receive.
839
840 // Check for streams that have been removed.
841 bool ret = true;
842 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
843 it != remote_streams_.end(); ++it) {
844 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
845 if (!RemoveRecvStream_w(it->first_ssrc())) {
846 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
847 << it->first_ssrc() << ".";
848 ret = false;
849 }
850 }
851 }
852 // Check for new streams.
853 for (StreamParamsVec::const_iterator it = streams.begin();
854 it != streams.end(); ++it) {
855 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc(), NULL)) {
856 if (AddRecvStream_w(*it)) {
857 LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
858 } else {
859 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
860 << it->first_ssrc();
861 ret = false;
862 }
863 }
864 }
865 remote_streams_ = streams;
866 return ret;
867 }
868
SetBaseLocalContent_w(const MediaContentDescription * content,ContentAction action)869 bool BaseChannel::SetBaseLocalContent_w(const MediaContentDescription* content,
870 ContentAction action) {
871 bool ret = UpdateLocalStreams_w(content->streams(), action);
872 // Set local SRTP parameters (what we will encrypt with).
873 ret &= SetSrtp_w(content->cryptos(), action, CS_LOCAL);
874 // Set local RTCP mux parameters.
875 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_LOCAL);
876 // Set local RTP header extensions.
877 if (content->rtp_header_extensions_set()) {
878 ret &= media_channel()->SetRecvRtpHeaderExtensions(
879 content->rtp_header_extensions());
880 }
881 return ret;
882 }
883
SetBaseRemoteContent_w(const MediaContentDescription * content,ContentAction action)884 bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content,
885 ContentAction action) {
886 bool ret = UpdateRemoteStreams_w(content->streams(), action);
887 // Set remote SRTP parameters (what the other side will encrypt with).
888 ret &= SetSrtp_w(content->cryptos(), action, CS_REMOTE);
889 // Set remote RTCP mux parameters.
890 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_REMOTE);
891 // Set remote RTP header extensions.
892 if (content->rtp_header_extensions_set()) {
893 ret &= media_channel()->SetSendRtpHeaderExtensions(
894 content->rtp_header_extensions());
895 }
896 return ret;
897 }
898
OnMessage(talk_base::Message * pmsg)899 void BaseChannel::OnMessage(talk_base::Message *pmsg) {
900 switch (pmsg->message_id) {
901 case MSG_ENABLE:
902 EnableMedia_w();
903 break;
904 case MSG_DISABLE:
905 DisableMedia_w();
906 break;
907
908 case MSG_MUTE:
909 MuteMedia_w();
910 break;
911 case MSG_UNMUTE:
912 UnmuteMedia_w();
913 break;
914 case MSG_SETLOCALCONTENT: {
915 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
916 data->result = SetLocalContent_w(data->content, data->action);
917 break;
918 }
919 case MSG_SETREMOTECONTENT: {
920 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
921 data->result = SetRemoteContent_w(data->content, data->action);
922 break;
923 }
924 case MSG_ADDRECVSTREAM: {
925 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
926 data->result = AddRecvStream_w(data->sp);
927 break;
928 }
929 case MSG_REMOVERECVSTREAM: {
930 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
931 data->result = RemoveRecvStream_w(data->ssrc);
932 break;
933 }
934 case MSG_SETMAXSENDBANDWIDTH: {
935 SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata);
936 data->result = SetMaxSendBandwidth_w(data->value);
937 break;
938 }
939
940 case MSG_RTPPACKET:
941 case MSG_RTCPPACKET: {
942 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata);
943 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet);
944 delete data; // because it is Posted
945 break;
946 }
947 }
948 }
949
Send(uint32 id,talk_base::MessageData * pdata)950 void BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) {
951 worker_thread_->Send(this, id, pdata);
952 }
953
Post(uint32 id,talk_base::MessageData * pdata)954 void BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) {
955 worker_thread_->Post(this, id, pdata);
956 }
957
PostDelayed(int cmsDelay,uint32 id,talk_base::MessageData * pdata)958 void BaseChannel::PostDelayed(int cmsDelay, uint32 id,
959 talk_base::MessageData *pdata) {
960 worker_thread_->PostDelayed(cmsDelay, this, id, pdata);
961 }
962
Clear(uint32 id,talk_base::MessageList * removed)963 void BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) {
964 worker_thread_->Clear(this, id, removed);
965 }
966
FlushRtcpMessages()967 void BaseChannel::FlushRtcpMessages() {
968 // Flush all remaining RTCP messages. This should only be called in
969 // destructor.
970 ASSERT(talk_base::Thread::Current() == worker_thread_);
971 talk_base::MessageList rtcp_messages;
972 Clear(MSG_RTCPPACKET, &rtcp_messages);
973 for (talk_base::MessageList::iterator it = rtcp_messages.begin();
974 it != rtcp_messages.end(); ++it) {
975 Send(MSG_RTCPPACKET, it->pdata);
976 }
977 }
978
VoiceChannel(talk_base::Thread * thread,MediaEngineInterface * media_engine,VoiceMediaChannel * media_channel,BaseSession * session,const std::string & content_name,bool rtcp)979 VoiceChannel::VoiceChannel(talk_base::Thread* thread,
980 MediaEngineInterface* media_engine,
981 VoiceMediaChannel* media_channel,
982 BaseSession* session,
983 const std::string& content_name,
984 bool rtcp)
985 : BaseChannel(thread, media_engine, media_channel, session, content_name,
986 rtcp),
987 received_media_(false),
988 mute_on_type_(false),
989 mute_on_type_timeout_(kTypingBlackoutPeriod) {
990 }
991
~VoiceChannel()992 VoiceChannel::~VoiceChannel() {
993 StopAudioMonitor();
994 StopMediaMonitor();
995 // this can't be done in the base class, since it calls a virtual
996 DisableMedia_w();
997 }
998
Init()999 bool VoiceChannel::Init() {
1000 TransportChannel* rtcp_channel = rtcp() ?
1001 session()->CreateChannel(content_name(), "rtcp") : NULL;
1002 if (!BaseChannel::Init(session()->CreateChannel(content_name(), "rtp"),
1003 rtcp_channel)) {
1004 return false;
1005 }
1006 media_channel()->SignalMediaError.connect(
1007 this, &VoiceChannel::OnVoiceChannelError);
1008 srtp_filter()->SignalSrtpError.connect(
1009 this, &VoiceChannel::OnSrtpError);
1010 return true;
1011 }
1012
SetRingbackTone(const void * buf,int len)1013 bool VoiceChannel::SetRingbackTone(const void* buf, int len) {
1014 SetRingbackToneMessageData data(buf, len);
1015 Send(MSG_SETRINGBACKTONE, &data);
1016 return data.result;
1017 }
1018
1019 // TODO: Handle early media the right way. We should get an explicit
1020 // ringing message telling us to start playing local ringback, which we cancel
1021 // if any early media actually arrives. For now, we do the opposite, which is
1022 // to wait 1 second for early media, and start playing local ringback if none
1023 // arrives.
SetEarlyMedia(bool enable)1024 void VoiceChannel::SetEarlyMedia(bool enable) {
1025 if (enable) {
1026 // Start the early media timeout
1027 PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT);
1028 } else {
1029 // Stop the timeout if currently going.
1030 Clear(MSG_EARLYMEDIATIMEOUT);
1031 }
1032 }
1033
PlayRingbackTone(uint32 ssrc,bool play,bool loop)1034 bool VoiceChannel::PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
1035 PlayRingbackToneMessageData data(ssrc, play, loop);
1036 Send(MSG_PLAYRINGBACKTONE, &data);
1037 return data.result;
1038 }
1039
PressDTMF(int digit,bool playout)1040 bool VoiceChannel::PressDTMF(int digit, bool playout) {
1041 DtmfMessageData data(digit, playout);
1042 Send(MSG_PRESSDTMF, &data);
1043 return data.result;
1044 }
1045
SetOutputScaling(uint32 ssrc,double left,double right)1046 bool VoiceChannel::SetOutputScaling(uint32 ssrc, double left, double right) {
1047 ScaleVolumeMessageData data(ssrc, left, right);
1048 Send(MSG_SCALEVOLUME, &data);
1049 return data.result;
1050 }
1051
StartMediaMonitor(int cms)1052 void VoiceChannel::StartMediaMonitor(int cms) {
1053 media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(),
1054 talk_base::Thread::Current()));
1055 media_monitor_->SignalUpdate.connect(
1056 this, &VoiceChannel::OnMediaMonitorUpdate);
1057 media_monitor_->Start(cms);
1058 }
1059
StopMediaMonitor()1060 void VoiceChannel::StopMediaMonitor() {
1061 if (media_monitor_.get()) {
1062 media_monitor_->Stop();
1063 media_monitor_->SignalUpdate.disconnect(this);
1064 media_monitor_.reset();
1065 }
1066 }
1067
StartAudioMonitor(int cms)1068 void VoiceChannel::StartAudioMonitor(int cms) {
1069 audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current()));
1070 audio_monitor_
1071 ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate);
1072 audio_monitor_->Start(cms);
1073 }
1074
StopAudioMonitor()1075 void VoiceChannel::StopAudioMonitor() {
1076 if (audio_monitor_.get()) {
1077 audio_monitor_->Stop();
1078 audio_monitor_.reset();
1079 }
1080 }
1081
IsAudioMonitorRunning() const1082 bool VoiceChannel::IsAudioMonitorRunning() const {
1083 return (audio_monitor_.get() != NULL);
1084 }
1085
GetInputLevel_w()1086 int VoiceChannel::GetInputLevel_w() {
1087 return media_engine()->GetInputLevel();
1088 }
1089
GetOutputLevel_w()1090 int VoiceChannel::GetOutputLevel_w() {
1091 return media_channel()->GetOutputLevel();
1092 }
1093
GetActiveStreams_w(AudioInfo::StreamList * actives)1094 void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) {
1095 media_channel()->GetActiveStreams(actives);
1096 }
1097
OnChannelRead(TransportChannel * channel,const char * data,size_t len)1098 void VoiceChannel::OnChannelRead(TransportChannel* channel,
1099 const char* data, size_t len) {
1100 BaseChannel::OnChannelRead(channel, data, len);
1101
1102 // Set a flag when we've received an RTP packet. If we're waiting for early
1103 // media, this will disable the timeout.
1104 if (!received_media_ && !PacketIsRtcp(channel, data, len)) {
1105 received_media_ = true;
1106 }
1107 }
1108
ChangeState()1109 void VoiceChannel::ChangeState() {
1110 // Render incoming data if we're the active call, and we have the local
1111 // content. We receive data on the default channel and multiplexed streams.
1112 bool recv = enabled() && has_local_content();
1113 if (!media_channel()->SetPlayout(recv)) {
1114 SendLastMediaError();
1115 }
1116
1117 // Send outgoing data if we're the active call, we have the remote content,
1118 // and we have had some form of connectivity.
1119 bool send = enabled() && has_remote_content() && was_ever_writable();
1120 SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING;
1121 if (!media_channel()->SetSend(send_flag)) {
1122 LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel";
1123 SendLastMediaError();
1124 }
1125
1126 LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
1127 }
1128
GetFirstContent(const SessionDescription * sdesc)1129 const MediaContentDescription* VoiceChannel::GetFirstContent(
1130 const SessionDescription* sdesc) {
1131 const ContentInfo* cinfo = GetFirstAudioContent(sdesc);
1132 if (cinfo == NULL)
1133 return NULL;
1134
1135 return static_cast<const MediaContentDescription*>(cinfo->description);
1136 }
1137
SetLocalContent_w(const MediaContentDescription * content,ContentAction action)1138 bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
1139 ContentAction action) {
1140 ASSERT(worker_thread() == talk_base::Thread::Current());
1141 LOG(LS_INFO) << "Setting local voice description";
1142
1143 const AudioContentDescription* audio =
1144 static_cast<const AudioContentDescription*>(content);
1145 ASSERT(audio != NULL);
1146 if (!audio) return false;
1147
1148 bool ret = SetBaseLocalContent_w(content, action);
1149 // Set local audio codecs (what we want to receive).
1150 // TODO: Change action != CA_UPDATE to !audio->partial() when partial
1151 // is set properly.
1152 if (action != CA_UPDATE || audio->has_codecs()) {
1153 ret &= media_channel()->SetRecvCodecs(audio->codecs());
1154 }
1155
1156 // If everything worked, see if we can start receiving.
1157 if (ret) {
1158 set_has_local_content(true);
1159 ChangeState();
1160 } else {
1161 LOG(LS_WARNING) << "Failed to set local voice description";
1162 }
1163 return ret;
1164 }
1165
SetRemoteContent_w(const MediaContentDescription * content,ContentAction action)1166 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
1167 ContentAction action) {
1168 ASSERT(worker_thread() == talk_base::Thread::Current());
1169 LOG(LS_INFO) << "Setting remote voice description";
1170
1171 const AudioContentDescription* audio =
1172 static_cast<const AudioContentDescription*>(content);
1173 ASSERT(audio != NULL);
1174 if (!audio) return false;
1175
1176 bool ret = true;
1177 // Set remote video codecs (what the other side wants to receive).
1178 if (action != CA_UPDATE || audio->has_codecs()) {
1179 ret &= media_channel()->SetSendCodecs(audio->codecs());
1180 }
1181
1182 ret &= SetBaseRemoteContent_w(content, action);
1183
1184 if (action != CA_UPDATE) {
1185 // Tweak our audio processing settings, if needed.
1186 int audio_options = media_channel()->GetOptions();
1187 if (audio->conference_mode()) {
1188 audio_options |= OPT_CONFERENCE;
1189 } else {
1190 audio_options &= (~OPT_CONFERENCE);
1191 }
1192 if (audio->agc_minus_10db()) {
1193 audio_options |= OPT_AGC_MINUS_10DB;
1194 } else {
1195 audio_options &= (~OPT_AGC_MINUS_10DB);
1196 }
1197 if (!media_channel()->SetOptions(audio_options)) {
1198 // Log an error on failure, but don't abort the call.
1199 LOG(LS_ERROR) << "Failed to set voice channel options";
1200 }
1201 }
1202
1203 // If everything worked, see if we can start sending.
1204 if (ret) {
1205 set_has_remote_content(true);
1206 ChangeState();
1207 } else {
1208 LOG(LS_WARNING) << "Failed to set remote voice description";
1209 }
1210 return ret;
1211 }
1212
SetRingbackTone_w(const void * buf,int len)1213 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) {
1214 ASSERT(worker_thread() == talk_base::Thread::Current());
1215 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len);
1216 }
1217
PlayRingbackTone_w(uint32 ssrc,bool play,bool loop)1218 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) {
1219 ASSERT(worker_thread() == talk_base::Thread::Current());
1220 if (play) {
1221 LOG(LS_INFO) << "Playing ringback tone, loop=" << loop;
1222 } else {
1223 LOG(LS_INFO) << "Stopping ringback tone";
1224 }
1225 return media_channel()->PlayRingbackTone(ssrc, play, loop);
1226 }
1227
HandleEarlyMediaTimeout()1228 void VoiceChannel::HandleEarlyMediaTimeout() {
1229 // This occurs on the main thread, not the worker thread.
1230 if (!received_media_) {
1231 LOG(LS_INFO) << "No early media received before timeout";
1232 SignalEarlyMediaTimeout(this);
1233 }
1234 }
1235
PressDTMF_w(int digit,bool playout)1236 bool VoiceChannel::PressDTMF_w(int digit, bool playout) {
1237 if (!enabled() || !writable()) {
1238 return false;
1239 }
1240
1241 return media_channel()->PressDTMF(digit, playout);
1242 }
1243
SetOutputScaling_w(uint32 ssrc,double left,double right)1244 bool VoiceChannel::SetOutputScaling_w(uint32 ssrc, double left, double right) {
1245 return media_channel()->SetOutputScaling(ssrc, left, right);
1246 }
1247
OnMessage(talk_base::Message * pmsg)1248 void VoiceChannel::OnMessage(talk_base::Message *pmsg) {
1249 switch (pmsg->message_id) {
1250 case MSG_SETRINGBACKTONE: {
1251 SetRingbackToneMessageData* data =
1252 static_cast<SetRingbackToneMessageData*>(pmsg->pdata);
1253 data->result = SetRingbackTone_w(data->buf, data->len);
1254 break;
1255 }
1256 case MSG_PLAYRINGBACKTONE: {
1257 PlayRingbackToneMessageData* data =
1258 static_cast<PlayRingbackToneMessageData*>(pmsg->pdata);
1259 data->result = PlayRingbackTone_w(data->ssrc, data->play, data->loop);
1260 break;
1261 }
1262 case MSG_EARLYMEDIATIMEOUT:
1263 HandleEarlyMediaTimeout();
1264 break;
1265 case MSG_PRESSDTMF: {
1266 DtmfMessageData* data = static_cast<DtmfMessageData*>(pmsg->pdata);
1267 data->result = PressDTMF_w(data->digit, data->playout);
1268 break;
1269 }
1270 case MSG_SCALEVOLUME: {
1271 ScaleVolumeMessageData* data =
1272 static_cast<ScaleVolumeMessageData*>(pmsg->pdata);
1273 data->result = SetOutputScaling_w(data->ssrc, data->left, data->right);
1274 break;
1275 }
1276 case MSG_CHANNEL_ERROR: {
1277 VoiceChannelErrorMessageData* data =
1278 static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata);
1279 SignalMediaError(this, data->ssrc, data->error);
1280 delete data;
1281 break;
1282 }
1283 default:
1284 BaseChannel::OnMessage(pmsg);
1285 break;
1286 }
1287 }
1288
OnConnectionMonitorUpdate(SocketMonitor * monitor,const std::vector<ConnectionInfo> & infos)1289 void VoiceChannel::OnConnectionMonitorUpdate(
1290 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
1291 SignalConnectionMonitor(this, infos);
1292 }
1293
OnMediaMonitorUpdate(VoiceMediaChannel * media_channel,const VoiceMediaInfo & info)1294 void VoiceChannel::OnMediaMonitorUpdate(
1295 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) {
1296 ASSERT(media_channel == this->media_channel());
1297 SignalMediaMonitor(this, info);
1298 }
1299
OnAudioMonitorUpdate(AudioMonitor * monitor,const AudioInfo & info)1300 void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor,
1301 const AudioInfo& info) {
1302 SignalAudioMonitor(this, info);
1303 }
1304
OnVoiceChannelError(uint32 ssrc,VoiceMediaChannel::Error err)1305 void VoiceChannel::OnVoiceChannelError(
1306 uint32 ssrc, VoiceMediaChannel::Error err) {
1307 if (err == VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED &&
1308 mute_on_type_ && !muted()) {
1309 Mute(true);
1310 PostDelayed(mute_on_type_timeout_, MSG_UNMUTE, NULL);
1311 }
1312 VoiceChannelErrorMessageData* data = new VoiceChannelErrorMessageData(
1313 ssrc, err);
1314 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
1315 }
1316
OnSrtpError(uint32 ssrc,SrtpFilter::Mode mode,SrtpFilter::Error error)1317 void VoiceChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
1318 SrtpFilter::Error error) {
1319 switch (error) {
1320 case SrtpFilter::ERROR_FAIL:
1321 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1322 VoiceMediaChannel::ERROR_REC_SRTP_ERROR :
1323 VoiceMediaChannel::ERROR_PLAY_SRTP_ERROR);
1324 break;
1325 case SrtpFilter::ERROR_AUTH:
1326 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1327 VoiceMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
1328 VoiceMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
1329 break;
1330 case SrtpFilter::ERROR_REPLAY:
1331 // Only receving channel should have this error.
1332 ASSERT(mode == SrtpFilter::UNPROTECT);
1333 OnVoiceChannelError(ssrc, VoiceMediaChannel::ERROR_PLAY_SRTP_REPLAY);
1334 break;
1335 default:
1336 break;
1337 }
1338 }
1339
VideoChannel(talk_base::Thread * thread,MediaEngineInterface * media_engine,VideoMediaChannel * media_channel,BaseSession * session,const std::string & content_name,bool rtcp,VoiceChannel * voice_channel)1340 VideoChannel::VideoChannel(talk_base::Thread* thread,
1341 MediaEngineInterface* media_engine,
1342 VideoMediaChannel* media_channel,
1343 BaseSession* session,
1344 const std::string& content_name,
1345 bool rtcp,
1346 VoiceChannel* voice_channel)
1347 : BaseChannel(thread, media_engine, media_channel, session, content_name,
1348 rtcp),
1349 voice_channel_(voice_channel), renderer_(NULL) {
1350 }
1351
Init()1352 bool VideoChannel::Init() {
1353 TransportChannel* rtcp_channel = rtcp() ?
1354 session()->CreateChannel(content_name(), "video_rtcp") : NULL;
1355 if (!BaseChannel::Init(
1356 session()->CreateChannel(content_name(), "video_rtp"),
1357 rtcp_channel)) {
1358 return false;
1359 }
1360 media_channel()->SignalScreencastWindowEvent.connect(
1361 this, &VideoChannel::OnScreencastWindowEvent);
1362 media_channel()->SignalMediaError.connect(
1363 this, &VideoChannel::OnVideoChannelError);
1364 srtp_filter()->SignalSrtpError.connect(
1365 this, &VideoChannel::OnSrtpError);
1366 return true;
1367 }
1368
SendLastMediaError()1369 void VoiceChannel::SendLastMediaError() {
1370 uint32 ssrc;
1371 VoiceMediaChannel::Error error;
1372 media_channel()->GetLastMediaError(&ssrc, &error);
1373 SignalMediaError(this, ssrc, error);
1374 }
1375
~VideoChannel()1376 VideoChannel::~VideoChannel() {
1377 StopMediaMonitor();
1378 // this can't be done in the base class, since it calls a virtual
1379 DisableMedia_w();
1380 }
1381
SetRenderer(uint32 ssrc,VideoRenderer * renderer)1382 bool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
1383 RenderMessageData data(ssrc, renderer);
1384 Send(MSG_SETRENDERER, &data);
1385 return true;
1386 }
1387
ApplyViewRequest(const ViewRequest & request)1388 bool VideoChannel::ApplyViewRequest(const ViewRequest& request) {
1389 ViewRequestMessageData data(request);
1390 Send(MSG_HANDLEVIEWREQUEST, &data);
1391 return data.result;
1392 }
1393
AddScreencast(uint32 ssrc,const ScreencastId & id,int fps)1394 bool VideoChannel::AddScreencast(uint32 ssrc, const ScreencastId& id, int fps) {
1395 ScreencastMessageData data(ssrc, id, fps);
1396 Send(MSG_ADDSCREENCAST, &data);
1397 return true;
1398 }
1399
RemoveScreencast(uint32 ssrc)1400 bool VideoChannel::RemoveScreencast(uint32 ssrc) {
1401 ScreencastMessageData data(ssrc, ScreencastId(), 0);
1402 Send(MSG_REMOVESCREENCAST, &data);
1403 return true;
1404 }
1405
SendIntraFrame()1406 bool VideoChannel::SendIntraFrame() {
1407 Send(MSG_SENDINTRAFRAME);
1408 return true;
1409 }
1410
RequestIntraFrame()1411 bool VideoChannel::RequestIntraFrame() {
1412 Send(MSG_REQUESTINTRAFRAME);
1413 return true;
1414 }
1415
ChangeState()1416 void VideoChannel::ChangeState() {
1417 // Render incoming data if we're the active call, and we have the local
1418 // content. We receive data on the default channel and multiplexed streams.
1419 bool recv = enabled() && has_local_content();
1420 if (!media_channel()->SetRender(recv)) {
1421 LOG(LS_ERROR) << "Failed to SetRender on video channel";
1422 // TODO: Report error back to server.
1423 }
1424
1425 // Send outgoing data if we're the active call, we have the remote content,
1426 // and we have had some form of connectivity.
1427 bool send = enabled() && has_remote_content() && was_ever_writable();
1428 if (!media_channel()->SetSend(send)) {
1429 LOG(LS_ERROR) << "Failed to SetSend on video channel";
1430 // TODO: Report error back to server.
1431 }
1432
1433 LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send;
1434 }
1435
StartMediaMonitor(int cms)1436 void VideoChannel::StartMediaMonitor(int cms) {
1437 media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(),
1438 talk_base::Thread::Current()));
1439 media_monitor_->SignalUpdate.connect(
1440 this, &VideoChannel::OnMediaMonitorUpdate);
1441 media_monitor_->Start(cms);
1442 }
1443
StopMediaMonitor()1444 void VideoChannel::StopMediaMonitor() {
1445 if (media_monitor_.get()) {
1446 media_monitor_->Stop();
1447 media_monitor_.reset();
1448 }
1449 }
1450
GetFirstContent(const SessionDescription * sdesc)1451 const MediaContentDescription* VideoChannel::GetFirstContent(
1452 const SessionDescription* sdesc) {
1453 const ContentInfo* cinfo = GetFirstVideoContent(sdesc);
1454 if (cinfo == NULL)
1455 return NULL;
1456
1457 return static_cast<const MediaContentDescription*>(cinfo->description);
1458 }
1459
SetLocalContent_w(const MediaContentDescription * content,ContentAction action)1460 bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
1461 ContentAction action) {
1462 ASSERT(worker_thread() == talk_base::Thread::Current());
1463 LOG(LS_INFO) << "Setting local video description";
1464
1465 const VideoContentDescription* video =
1466 static_cast<const VideoContentDescription*>(content);
1467 ASSERT(video != NULL);
1468 if (!video) return false;
1469
1470 bool ret = SetBaseLocalContent_w(content, action);
1471 // Set local video codecs (what we want to receive).
1472 if (action != CA_UPDATE || video->has_codecs()) {
1473 ret &= media_channel()->SetRecvCodecs(video->codecs());
1474 }
1475
1476 // If everything worked, see if we can start receiving.
1477 if (ret) {
1478 set_has_local_content(true);
1479 ChangeState();
1480 } else {
1481 LOG(LS_WARNING) << "Failed to set local video description";
1482 }
1483 return ret;
1484 }
1485
SetRemoteContent_w(const MediaContentDescription * content,ContentAction action)1486 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
1487 ContentAction action) {
1488 ASSERT(worker_thread() == talk_base::Thread::Current());
1489 LOG(LS_INFO) << "Setting remote video description";
1490
1491 const VideoContentDescription* video =
1492 static_cast<const VideoContentDescription*>(content);
1493 ASSERT(video != NULL);
1494 if (!video) return false;
1495
1496 bool ret = true;
1497 // Set remote video codecs (what the other side wants to receive).
1498 if (action != CA_UPDATE || video->has_codecs()) {
1499 ret &= media_channel()->SetSendCodecs(video->codecs());
1500 }
1501
1502 ret &= SetBaseRemoteContent_w(content, action);
1503
1504 if (action != CA_UPDATE) {
1505 // Tweak our video processing settings, if needed.
1506 int video_options = media_channel()->GetOptions();
1507 if (video->conference_mode()) {
1508 video_options |= OPT_CONFERENCE;
1509 } else {
1510 video_options &= (~OPT_CONFERENCE);
1511 }
1512 if (!media_channel()->SetOptions(video_options)) {
1513 // Log an error on failure, but don't abort the call.
1514 LOG(LS_ERROR) << "Failed to set video channel options";
1515 }
1516 // Set bandwidth parameters (what the other side wants to get, default=auto)
1517 int bandwidth_bps = video->bandwidth();
1518 bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth);
1519 ret &= media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps);
1520 }
1521
1522 // If everything worked, see if we can start sending.
1523 if (ret) {
1524 set_has_remote_content(true);
1525 ChangeState();
1526 } else {
1527 LOG(LS_WARNING) << "Failed to set remote video description";
1528 }
1529 return ret;
1530 }
1531
ApplyViewRequest_w(const ViewRequest & request)1532 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) {
1533 bool ret = true;
1534 // Set the send format for each of the local streams. If the view request
1535 // does not contain a local stream, set its send format to 0x0, which will
1536 // drop all frames.
1537 for (std::vector<StreamParams>::const_iterator it = local_streams().begin();
1538 it != local_streams().end(); ++it) {
1539 VideoFormat format(0, 0, 0, cricket::FOURCC_I420);
1540 StaticVideoViews::const_iterator view;
1541 for (view = request.static_video_views.begin();
1542 view != request.static_video_views.end(); ++view) {
1543 // Sender view request from Reflector has SSRC 0 (b/5977302). Here we hack
1544 // the client to apply the view request with SSRC 0. TODO: Remove
1545 // 0 == view->SSRC once Reflector uses the correct SSRC in view request.
1546 if (it->has_ssrc(view->ssrc) || 0 == view->ssrc) {
1547 format.width = view->width;
1548 format.height = view->height;
1549 format.interval = cricket::VideoFormat::FpsToInterval(view->framerate);
1550 break;
1551 }
1552 }
1553
1554 ret &= media_channel()->SetSendStreamFormat(it->first_ssrc(), format);
1555 }
1556
1557 // Check if the view request has invalid streams.
1558 for (StaticVideoViews::const_iterator it = request.static_video_views.begin();
1559 it != request.static_video_views.end(); ++it) {
1560 if (!GetStreamBySsrc(local_streams(), it->ssrc, NULL)) {
1561 LOG(LS_WARNING) << "View request's SSRC " << it->ssrc
1562 << " is not in the local streams.";
1563 }
1564 }
1565
1566 return ret;
1567 }
1568
SetRenderer_w(uint32 ssrc,VideoRenderer * renderer)1569 void VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) {
1570 media_channel()->SetRenderer(ssrc, renderer);
1571 }
1572
AddScreencast_w(uint32 ssrc,const ScreencastId & id,int fps)1573 void VideoChannel::AddScreencast_w(uint32 ssrc, const ScreencastId& id,
1574 int fps) {
1575 media_channel()->AddScreencast(ssrc, id, fps);
1576 }
1577
RemoveScreencast_w(uint32 ssrc)1578 void VideoChannel::RemoveScreencast_w(uint32 ssrc) {
1579 media_channel()->RemoveScreencast(ssrc);
1580 }
1581
OnScreencastWindowEvent_s(uint32 ssrc,talk_base::WindowEvent we)1582 void VideoChannel::OnScreencastWindowEvent_s(uint32 ssrc,
1583 talk_base::WindowEvent we) {
1584 ASSERT(signaling_thread() == talk_base::Thread::Current());
1585 SignalScreencastWindowEvent(ssrc, we);
1586 }
1587
OnMessage(talk_base::Message * pmsg)1588 void VideoChannel::OnMessage(talk_base::Message *pmsg) {
1589 switch (pmsg->message_id) {
1590 case MSG_SETRENDERER: {
1591 const RenderMessageData* data =
1592 static_cast<RenderMessageData*>(pmsg->pdata);
1593 SetRenderer_w(data->ssrc, data->renderer);
1594 break;
1595 }
1596 case MSG_ADDSCREENCAST: {
1597 const ScreencastMessageData* data =
1598 static_cast<ScreencastMessageData*>(pmsg->pdata);
1599 AddScreencast_w(data->ssrc, data->window_id, data->fps);
1600 break;
1601 }
1602 case MSG_REMOVESCREENCAST: {
1603 const ScreencastMessageData* data =
1604 static_cast<ScreencastMessageData*>(pmsg->pdata);
1605 RemoveScreencast_w(data->ssrc);
1606 break;
1607 }
1608 case MSG_SCREENCASTWINDOWEVENT: {
1609 const ScreencastEventMessageData* data =
1610 static_cast<ScreencastEventMessageData*>(pmsg->pdata);
1611 OnScreencastWindowEvent_s(data->ssrc, data->event);
1612 delete data;
1613 break;
1614 }
1615 case MSG_SENDINTRAFRAME: {
1616 SendIntraFrame_w();
1617 break;
1618 }
1619 case MSG_REQUESTINTRAFRAME: {
1620 RequestIntraFrame_w();
1621 break;
1622 }
1623 case MSG_SETCHANNELOPTIONS: {
1624 const ChannelOptionsMessageData* data =
1625 static_cast<ChannelOptionsMessageData*>(pmsg->pdata);
1626 SetChannelOptions_w(data->options);
1627 break;
1628 }
1629 case MSG_CHANNEL_ERROR: {
1630 const VideoChannelErrorMessageData* data =
1631 static_cast<VideoChannelErrorMessageData*>(pmsg->pdata);
1632 SignalMediaError(this, data->ssrc, data->error);
1633 delete data;
1634 break;
1635 }
1636 case MSG_HANDLEVIEWREQUEST: {
1637 ViewRequestMessageData* data =
1638 static_cast<ViewRequestMessageData*>(pmsg->pdata);
1639 data->result = ApplyViewRequest_w(data->request);
1640 break;
1641 }
1642 default:
1643 BaseChannel::OnMessage(pmsg);
1644 break;
1645 }
1646 }
1647
OnConnectionMonitorUpdate(SocketMonitor * monitor,const std::vector<ConnectionInfo> & infos)1648 void VideoChannel::OnConnectionMonitorUpdate(
1649 SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) {
1650 SignalConnectionMonitor(this, infos);
1651 }
1652
1653 // TODO: Look into removing duplicate code between
1654 // audio, video, and data, perhaps by using templates.
OnMediaMonitorUpdate(VideoMediaChannel * media_channel,const VideoMediaInfo & info)1655 void VideoChannel::OnMediaMonitorUpdate(
1656 VideoMediaChannel* media_channel, const VideoMediaInfo &info) {
1657 ASSERT(media_channel == this->media_channel());
1658 SignalMediaMonitor(this, info);
1659 }
1660
OnScreencastWindowEvent(uint32 ssrc,talk_base::WindowEvent event)1661 void VideoChannel::OnScreencastWindowEvent(uint32 ssrc,
1662 talk_base::WindowEvent event) {
1663 ScreencastEventMessageData* pdata =
1664 new ScreencastEventMessageData(ssrc, event);
1665 signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
1666 }
1667
OnVideoChannelError(uint32 ssrc,VideoMediaChannel::Error error)1668 void VideoChannel::OnVideoChannelError(uint32 ssrc,
1669 VideoMediaChannel::Error error) {
1670 VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData(
1671 ssrc, error);
1672 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
1673 }
1674
OnSrtpError(uint32 ssrc,SrtpFilter::Mode mode,SrtpFilter::Error error)1675 void VideoChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
1676 SrtpFilter::Error error) {
1677 switch (error) {
1678 case SrtpFilter::ERROR_FAIL:
1679 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1680 VideoMediaChannel::ERROR_REC_SRTP_ERROR :
1681 VideoMediaChannel::ERROR_PLAY_SRTP_ERROR);
1682 break;
1683 case SrtpFilter::ERROR_AUTH:
1684 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1685 VideoMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
1686 VideoMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
1687 break;
1688 case SrtpFilter::ERROR_REPLAY:
1689 // Only receving channel should have this error.
1690 ASSERT(mode == SrtpFilter::UNPROTECT);
1691 // TODO: Turn on the signaling of replay error once we have
1692 // switched to the new mechanism for doing video retransmissions.
1693 // OnVideoChannelError(ssrc, VideoMediaChannel::ERROR_PLAY_SRTP_REPLAY);
1694 break;
1695 default:
1696 break;
1697 }
1698 }
1699
DataChannel(talk_base::Thread * thread,DataMediaChannel * media_channel,BaseSession * session,const std::string & content_name,bool rtcp)1700 DataChannel::DataChannel(talk_base::Thread* thread,
1701 DataMediaChannel* media_channel,
1702 BaseSession* session,
1703 const std::string& content_name,
1704 bool rtcp)
1705 // MediaEngine is NULL
1706 : BaseChannel(thread, NULL, media_channel, session, content_name, rtcp) {
1707 }
1708
~DataChannel()1709 DataChannel::~DataChannel() {
1710 StopMediaMonitor();
1711 // this can't be done in the base class, since it calls a virtual
1712 DisableMedia_w();
1713 }
1714
Init()1715 bool DataChannel::Init() {
1716 TransportChannel* rtcp_channel = rtcp() ?
1717 session()->CreateChannel(content_name(), "data_rtcp") : NULL;
1718 if (!BaseChannel::Init(session()->CreateChannel(content_name(), "data_rtp"),
1719 rtcp_channel)) {
1720 return false;
1721 }
1722 media_channel()->SignalDataReceived.connect(
1723 this, &DataChannel::OnDataReceived);
1724 media_channel()->SignalMediaError.connect(
1725 this, &DataChannel::OnDataChannelError);
1726 srtp_filter()->SignalSrtpError.connect(
1727 this, &DataChannel::OnSrtpError);
1728 return true;
1729 }
1730
SendData(const DataMediaChannel::SendDataParams & params,const std::string & data)1731 bool DataChannel::SendData(
1732 const DataMediaChannel::SendDataParams& params,
1733 const std::string& data) {
1734 SendDataMessageData message_data(params, data);
1735 Send(MSG_SENDDATA, &message_data);
1736 return true;
1737 }
1738
GetFirstContent(const SessionDescription * sdesc)1739 const MediaContentDescription* DataChannel::GetFirstContent(
1740 const SessionDescription* sdesc) {
1741 const ContentInfo* cinfo = GetFirstDataContent(sdesc);
1742 if (cinfo == NULL)
1743 return NULL;
1744
1745 return static_cast<const MediaContentDescription*>(cinfo->description);
1746 }
1747
SetLocalContent_w(const MediaContentDescription * content,ContentAction action)1748 bool DataChannel::SetLocalContent_w(const MediaContentDescription* content,
1749 ContentAction action) {
1750 ASSERT(worker_thread() == talk_base::Thread::Current());
1751 LOG(LS_INFO) << "Setting local data description";
1752
1753 const DataContentDescription* data =
1754 static_cast<const DataContentDescription*>(content);
1755 ASSERT(data != NULL);
1756 if (!data) return false;
1757
1758 bool ret = SetBaseLocalContent_w(content, action);
1759
1760 if (action != CA_UPDATE || data->has_codecs()) {
1761 ret &= media_channel()->SetRecvCodecs(data->codecs());
1762 }
1763
1764 // If everything worked, see if we can start receiving.
1765 if (ret) {
1766 set_has_local_content(true);
1767 ChangeState();
1768 } else {
1769 LOG(LS_WARNING) << "Failed to set local data description";
1770 }
1771 return ret;
1772 }
1773
SetRemoteContent_w(const MediaContentDescription * content,ContentAction action)1774 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content,
1775 ContentAction action) {
1776 ASSERT(worker_thread() == talk_base::Thread::Current());
1777
1778 const DataContentDescription* data =
1779 static_cast<const DataContentDescription*>(content);
1780 ASSERT(data != NULL);
1781 if (!data) return false;
1782
1783 // If the remote data doesn't have codecs and isn't an update, it
1784 // must be empty, so ignore it.
1785 if (action != CA_UPDATE && !data->has_codecs()) {
1786 return true;
1787 }
1788 LOG(LS_INFO) << "Setting remote data description";
1789
1790 bool ret = true;
1791 // Set remote video codecs (what the other side wants to receive).
1792 if (action != CA_UPDATE || data->has_codecs()) {
1793 ret &= media_channel()->SetSendCodecs(data->codecs());
1794 }
1795
1796 if (ret) {
1797 ret &= SetBaseRemoteContent_w(content, action);
1798 }
1799
1800 if (action != CA_UPDATE) {
1801 int bandwidth_bps = data->bandwidth();
1802 bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth);
1803 ret &= media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps);
1804 }
1805
1806 // If everything worked, see if we can start sending.
1807 if (ret) {
1808 set_has_remote_content(true);
1809 ChangeState();
1810 } else {
1811 LOG(LS_WARNING) << "Failed to set remote data description";
1812 }
1813 return ret;
1814 }
1815
ChangeState()1816 void DataChannel::ChangeState() {
1817 // Render incoming data if we're the active call, and we have the local
1818 // content. We receive data on the default channel and multiplexed streams.
1819 bool recv = enabled() && has_local_content();
1820 if (!media_channel()->SetReceive(recv)) {
1821 LOG(LS_ERROR) << "Failed to SetReceive on data channel";
1822 }
1823
1824 // Send outgoing data if we're the active call, we have the remote content,
1825 // and we have had some form of connectivity.
1826 bool send = enabled() && has_remote_content() && was_ever_writable();
1827 if (!media_channel()->SetSend(send)) {
1828 LOG(LS_ERROR) << "Failed to SetSend on data channel";
1829 }
1830
1831 LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
1832 }
1833
OnMessage(talk_base::Message * pmsg)1834 void DataChannel::OnMessage(talk_base::Message *pmsg) {
1835 switch (pmsg->message_id) {
1836 case MSG_SENDDATA: {
1837 SendDataMessageData* data =
1838 static_cast<SendDataMessageData*>(pmsg->pdata);
1839 // TODO: use return value?
1840 media_channel()->SendData(data->params, data->data);
1841 break;
1842 }
1843 case MSG_DATARECEIVED: {
1844 DataReceivedMessageData* data =
1845 static_cast<DataReceivedMessageData*>(pmsg->pdata);
1846 SignalDataReceived(this, data->params, data->data);
1847 delete data;
1848 break;
1849 }
1850 case MSG_CHANNEL_ERROR: {
1851 const DataChannelErrorMessageData* data =
1852 static_cast<DataChannelErrorMessageData*>(pmsg->pdata);
1853 SignalMediaError(this, data->ssrc, data->error);
1854 delete data;
1855 break;
1856 }
1857 default:
1858 BaseChannel::OnMessage(pmsg);
1859 break;
1860 }
1861 }
1862
OnConnectionMonitorUpdate(SocketMonitor * monitor,const std::vector<ConnectionInfo> & infos)1863 void DataChannel::OnConnectionMonitorUpdate(
1864 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
1865 SignalConnectionMonitor(this, infos);
1866 }
1867
StartMediaMonitor(int cms)1868 void DataChannel::StartMediaMonitor(int cms) {
1869 media_monitor_.reset(new DataMediaMonitor(media_channel(), worker_thread(),
1870 talk_base::Thread::Current()));
1871 media_monitor_->SignalUpdate.connect(
1872 this, &DataChannel::OnMediaMonitorUpdate);
1873 media_monitor_->Start(cms);
1874 }
1875
StopMediaMonitor()1876 void DataChannel::StopMediaMonitor() {
1877 if (media_monitor_.get()) {
1878 media_monitor_->Stop();
1879 media_monitor_->SignalUpdate.disconnect(this);
1880 media_monitor_.reset();
1881 }
1882 }
1883
OnMediaMonitorUpdate(DataMediaChannel * media_channel,const DataMediaInfo & info)1884 void DataChannel::OnMediaMonitorUpdate(
1885 DataMediaChannel* media_channel, const DataMediaInfo& info) {
1886 ASSERT(media_channel == this->media_channel());
1887 SignalMediaMonitor(this, info);
1888 }
1889
OnDataReceived(const ReceiveDataParams & params,const char * data,size_t len)1890 void DataChannel::OnDataReceived(
1891 const ReceiveDataParams& params, const char* data, size_t len) {
1892 DataReceivedMessageData* msg = new DataReceivedMessageData(
1893 params, data, len);
1894 signaling_thread()->Post(this, MSG_DATARECEIVED, msg);
1895 }
1896
OnDataChannelError(uint32 ssrc,DataMediaChannel::Error err)1897 void DataChannel::OnDataChannelError(
1898 uint32 ssrc, DataMediaChannel::Error err) {
1899 DataChannelErrorMessageData* data = new DataChannelErrorMessageData(
1900 ssrc, err);
1901 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
1902 }
1903
OnSrtpError(uint32 ssrc,SrtpFilter::Mode mode,SrtpFilter::Error error)1904 void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
1905 SrtpFilter::Error error) {
1906 switch (error) {
1907 case SrtpFilter::ERROR_FAIL:
1908 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1909 DataMediaChannel::ERROR_SEND_SRTP_ERROR :
1910 DataMediaChannel::ERROR_RECV_SRTP_ERROR);
1911 break;
1912 case SrtpFilter::ERROR_AUTH:
1913 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1914 DataMediaChannel::ERROR_SEND_SRTP_AUTH_FAILED :
1915 DataMediaChannel::ERROR_RECV_SRTP_AUTH_FAILED);
1916 break;
1917 case SrtpFilter::ERROR_REPLAY:
1918 // Only receving channel should have this error.
1919 ASSERT(mode == SrtpFilter::UNPROTECT);
1920 OnDataChannelError(ssrc, DataMediaChannel::ERROR_RECV_SRTP_REPLAY);
1921 break;
1922 default:
1923 break;
1924 }
1925 }
1926
1927 } // namespace cricket
1928