blob: 66f4054018f0e62c55c8cd2e3ddcc57c5e95b1e1 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004 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/media/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/media/base/rtputils.h"
35#include "talk/p2p/base/transportchannel.h"
36#include "talk/session/media/channelmanager.h"
37#include "talk/session/media/mediamessages.h"
38#include "talk/session/media/rtcpmuxfilter.h"
39#include "talk/session/media/typingmonitor.h"
40
41
42namespace cricket {
43
44enum {
45 MSG_ENABLE = 1,
46 MSG_DISABLE,
47 MSG_MUTESTREAM,
48 MSG_ISSTREAMMUTED,
49 MSG_SETREMOTECONTENT,
50 MSG_SETLOCALCONTENT,
51 MSG_EARLYMEDIATIMEOUT,
52 MSG_CANINSERTDTMF,
53 MSG_INSERTDTMF,
54 MSG_GETSTATS,
55 MSG_SETRENDERER,
56 MSG_ADDRECVSTREAM,
57 MSG_REMOVERECVSTREAM,
58 MSG_SETRINGBACKTONE,
59 MSG_PLAYRINGBACKTONE,
60 MSG_SETMAXSENDBANDWIDTH,
61 MSG_ADDSCREENCAST,
62 MSG_REMOVESCREENCAST,
63 MSG_SENDINTRAFRAME,
64 MSG_REQUESTINTRAFRAME,
65 MSG_SCREENCASTWINDOWEVENT,
66 MSG_RTPPACKET,
67 MSG_RTCPPACKET,
68 MSG_CHANNEL_ERROR,
69 MSG_SETCHANNELOPTIONS,
70 MSG_SCALEVOLUME,
71 MSG_HANDLEVIEWREQUEST,
72 MSG_READYTOSENDDATA,
73 MSG_SENDDATA,
74 MSG_DATARECEIVED,
75 MSG_SETCAPTURER,
76 MSG_ISSCREENCASTING,
77 MSG_SCREENCASTFPS,
78 MSG_SETSCREENCASTFACTORY,
79 MSG_FIRSTPACKETRECEIVED,
80 MSG_SESSION_ERROR,
81};
82
83// Value specified in RFC 5764.
84static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp";
85
86static const int kAgcMinus10db = -10;
87
88// TODO(hellner): use the device manager for creation of screen capturers when
89// the cl enabling it has landed.
90class NullScreenCapturerFactory : public VideoChannel::ScreenCapturerFactory {
91 public:
92 VideoCapturer* CreateScreenCapturer(const ScreencastId& window) {
93 return NULL;
94 }
95};
96
97
98VideoChannel::ScreenCapturerFactory* CreateScreenCapturerFactory() {
99 return new NullScreenCapturerFactory();
100}
101
102struct SetContentData : public talk_base::MessageData {
103 SetContentData(const MediaContentDescription* content, ContentAction action)
104 : content(content),
105 action(action),
106 result(false) {
107 }
108 const MediaContentDescription* content;
109 ContentAction action;
110 bool result;
111};
112
113struct SetBandwidthData : public talk_base::MessageData {
114 explicit SetBandwidthData(int value) : value(value), result(false) {}
115 int value;
116 bool result;
117};
118
119struct SetRingbackToneMessageData : public talk_base::MessageData {
120 SetRingbackToneMessageData(const void* b, int l)
121 : buf(b),
122 len(l),
123 result(false) {
124 }
125 const void* buf;
126 int len;
127 bool result;
128};
129
130struct PlayRingbackToneMessageData : public talk_base::MessageData {
131 PlayRingbackToneMessageData(uint32 s, bool p, bool l)
132 : ssrc(s),
133 play(p),
134 loop(l),
135 result(false) {
136 }
137 uint32 ssrc;
138 bool play;
139 bool loop;
140 bool result;
141};
142typedef talk_base::TypedMessageData<bool> BoolMessageData;
143struct DtmfMessageData : public talk_base::MessageData {
144 DtmfMessageData(uint32 ssrc, int event, int duration, int flags)
145 : ssrc(ssrc),
146 event(event),
147 duration(duration),
148 flags(flags),
149 result(false) {
150 }
151 uint32 ssrc;
152 int event;
153 int duration;
154 int flags;
155 bool result;
156};
157struct ScaleVolumeMessageData : public talk_base::MessageData {
158 ScaleVolumeMessageData(uint32 s, double l, double r)
159 : ssrc(s),
160 left(l),
161 right(r),
162 result(false) {
163 }
164 uint32 ssrc;
165 double left;
166 double right;
167 bool result;
168};
169
170struct VoiceStatsMessageData : public talk_base::MessageData {
171 explicit VoiceStatsMessageData(VoiceMediaInfo* stats)
172 : result(false),
173 stats(stats) {
174 }
175 bool result;
176 VoiceMediaInfo* stats;
177};
178
179struct VideoStatsMessageData : public talk_base::MessageData {
180 explicit VideoStatsMessageData(VideoMediaInfo* stats)
181 : result(false),
182 stats(stats) {
183 }
184 bool result;
185 VideoMediaInfo* stats;
186};
187
188struct PacketMessageData : public talk_base::MessageData {
189 talk_base::Buffer packet;
190};
191
192struct AudioRenderMessageData: public talk_base::MessageData {
193 AudioRenderMessageData(uint32 s, AudioRenderer* r)
194 : ssrc(s), renderer(r), result(false) {}
195 uint32 ssrc;
196 AudioRenderer* renderer;
197 bool result;
198};
199
200struct VideoRenderMessageData : public talk_base::MessageData {
201 VideoRenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
202 uint32 ssrc;
203 VideoRenderer* renderer;
204};
205
206struct AddScreencastMessageData : public talk_base::MessageData {
207 AddScreencastMessageData(uint32 s, const ScreencastId& id)
208 : ssrc(s),
209 window_id(id),
210 result(NULL) {
211 }
212 uint32 ssrc;
213 ScreencastId window_id;
214 VideoCapturer* result;
215};
216
217struct RemoveScreencastMessageData : public talk_base::MessageData {
218 explicit RemoveScreencastMessageData(uint32 s) : ssrc(s), result(false) {}
219 uint32 ssrc;
220 bool result;
221};
222
223struct ScreencastEventMessageData : public talk_base::MessageData {
224 ScreencastEventMessageData(uint32 s, talk_base::WindowEvent we)
225 : ssrc(s),
226 event(we) {
227 }
228 uint32 ssrc;
229 talk_base::WindowEvent event;
230};
231
232struct ViewRequestMessageData : public talk_base::MessageData {
233 explicit ViewRequestMessageData(const ViewRequest& r)
234 : request(r),
235 result(false) {
236 }
237 ViewRequest request;
238 bool result;
239};
240
241struct VoiceChannelErrorMessageData : public talk_base::MessageData {
242 VoiceChannelErrorMessageData(uint32 in_ssrc,
243 VoiceMediaChannel::Error in_error)
244 : ssrc(in_ssrc),
245 error(in_error) {
246 }
247 uint32 ssrc;
248 VoiceMediaChannel::Error error;
249};
250
251struct VideoChannelErrorMessageData : public talk_base::MessageData {
252 VideoChannelErrorMessageData(uint32 in_ssrc,
253 VideoMediaChannel::Error in_error)
254 : ssrc(in_ssrc),
255 error(in_error) {
256 }
257 uint32 ssrc;
258 VideoMediaChannel::Error error;
259};
260
261struct DataChannelErrorMessageData : public talk_base::MessageData {
262 DataChannelErrorMessageData(uint32 in_ssrc,
263 DataMediaChannel::Error in_error)
264 : ssrc(in_ssrc),
265 error(in_error) {}
266 uint32 ssrc;
267 DataMediaChannel::Error error;
268};
269
270struct SessionErrorMessageData : public talk_base::MessageData {
271 explicit SessionErrorMessageData(cricket::BaseSession::Error error)
272 : error_(error) {}
273
274 BaseSession::Error error_;
275};
276
277struct SsrcMessageData : public talk_base::MessageData {
278 explicit SsrcMessageData(uint32 ssrc) : ssrc(ssrc), result(false) {}
279 uint32 ssrc;
280 bool result;
281};
282
283struct StreamMessageData : public talk_base::MessageData {
284 explicit StreamMessageData(const StreamParams& in_sp)
285 : sp(in_sp),
286 result(false) {
287 }
288 StreamParams sp;
289 bool result;
290};
291
292struct MuteStreamData : public talk_base::MessageData {
293 MuteStreamData(uint32 ssrc, bool mute)
294 : ssrc(ssrc), mute(mute), result(false) {}
295 uint32 ssrc;
296 bool mute;
297 bool result;
298};
299
300struct AudioOptionsMessageData : public talk_base::MessageData {
301 explicit AudioOptionsMessageData(const AudioOptions& options)
302 : options(options),
303 result(false) {
304 }
305 AudioOptions options;
306 bool result;
307};
308
309struct VideoOptionsMessageData : public talk_base::MessageData {
310 explicit VideoOptionsMessageData(const VideoOptions& options)
311 : options(options),
312 result(false) {
313 }
314 VideoOptions options;
315 bool result;
316};
317
318struct SetCapturerMessageData : public talk_base::MessageData {
319 SetCapturerMessageData(uint32 s, VideoCapturer* c)
320 : ssrc(s),
321 capturer(c),
322 result(false) {
323 }
324 uint32 ssrc;
325 VideoCapturer* capturer;
326 bool result;
327};
328
329struct IsScreencastingMessageData : public talk_base::MessageData {
330 IsScreencastingMessageData()
331 : result(false) {
332 }
333 bool result;
334};
335
336struct ScreencastFpsMessageData : public talk_base::MessageData {
337 explicit ScreencastFpsMessageData(uint32 s)
338 : ssrc(s), result(0) {
339 }
340 uint32 ssrc;
341 int result;
342};
343
344struct SetScreenCaptureFactoryMessageData : public talk_base::MessageData {
345 explicit SetScreenCaptureFactoryMessageData(
346 VideoChannel::ScreenCapturerFactory* f)
347 : screencapture_factory(f) {
348 }
349 VideoChannel::ScreenCapturerFactory* screencapture_factory;
350};
351
352static const char* PacketType(bool rtcp) {
353 return (!rtcp) ? "RTP" : "RTCP";
354}
355
356static bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) {
357 // Check the packet size. We could check the header too if needed.
358 return (packet &&
359 packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) &&
360 packet->length() <= kMaxRtpPacketLen);
361}
362
363static bool IsReceiveContentDirection(MediaContentDirection direction) {
364 return direction == MD_SENDRECV || direction == MD_RECVONLY;
365}
366
367static bool IsSendContentDirection(MediaContentDirection direction) {
368 return direction == MD_SENDRECV || direction == MD_SENDONLY;
369}
370
371static const MediaContentDescription* GetContentDescription(
372 const ContentInfo* cinfo) {
373 if (cinfo == NULL)
374 return NULL;
375 return static_cast<const MediaContentDescription*>(cinfo->description);
376}
377
378BaseChannel::BaseChannel(talk_base::Thread* thread,
379 MediaEngineInterface* media_engine,
380 MediaChannel* media_channel, BaseSession* session,
381 const std::string& content_name, bool rtcp)
382 : worker_thread_(thread),
383 media_engine_(media_engine),
384 session_(session),
385 media_channel_(media_channel),
386 content_name_(content_name),
387 rtcp_(rtcp),
388 transport_channel_(NULL),
389 rtcp_transport_channel_(NULL),
390 enabled_(false),
391 writable_(false),
392 rtp_ready_to_send_(false),
393 rtcp_ready_to_send_(false),
394 optimistic_data_send_(false),
395 was_ever_writable_(false),
396 local_content_direction_(MD_INACTIVE),
397 remote_content_direction_(MD_INACTIVE),
398 has_received_packet_(false),
399 dtls_keyed_(false),
400 secure_required_(false) {
401 ASSERT(worker_thread_ == talk_base::Thread::Current());
402 LOG(LS_INFO) << "Created channel for " << content_name;
403}
404
405BaseChannel::~BaseChannel() {
406 ASSERT(worker_thread_ == talk_base::Thread::Current());
407 StopConnectionMonitor();
408 FlushRtcpMessages(); // Send any outstanding RTCP packets.
409 Clear(); // eats any outstanding messages or packets
410 // We must destroy the media channel before the transport channel, otherwise
411 // the media channel may try to send on the dead transport channel. NULLing
412 // is not an effective strategy since the sends will come on another thread.
413 delete media_channel_;
414 set_rtcp_transport_channel(NULL);
415 if (transport_channel_ != NULL)
416 session_->DestroyChannel(content_name_, transport_channel_->component());
417 LOG(LS_INFO) << "Destroyed channel";
418}
419
420bool BaseChannel::Init(TransportChannel* transport_channel,
421 TransportChannel* rtcp_transport_channel) {
422 if (transport_channel == NULL) {
423 return false;
424 }
425 if (rtcp() && rtcp_transport_channel == NULL) {
426 return false;
427 }
428 transport_channel_ = transport_channel;
429
430 if (!SetDtlsSrtpCiphers(transport_channel_, false)) {
431 return false;
432 }
433
434 media_channel_->SetInterface(this);
435 transport_channel_->SignalWritableState.connect(
436 this, &BaseChannel::OnWritableState);
437 transport_channel_->SignalReadPacket.connect(
438 this, &BaseChannel::OnChannelRead);
439 transport_channel_->SignalReadyToSend.connect(
440 this, &BaseChannel::OnReadyToSend);
441
442 session_->SignalNewLocalDescription.connect(
443 this, &BaseChannel::OnNewLocalDescription);
444 session_->SignalNewRemoteDescription.connect(
445 this, &BaseChannel::OnNewRemoteDescription);
446
447 set_rtcp_transport_channel(rtcp_transport_channel);
448 return true;
449}
450
451// Can be called from thread other than worker thread
452bool BaseChannel::Enable(bool enable) {
453 Send(enable ? MSG_ENABLE : MSG_DISABLE);
454 return true;
455}
456
457// Can be called from thread other than worker thread
458bool BaseChannel::MuteStream(uint32 ssrc, bool mute) {
459 MuteStreamData data(ssrc, mute);
460 Send(MSG_MUTESTREAM, &data);
461 return data.result;
462}
463
464bool BaseChannel::IsStreamMuted(uint32 ssrc) {
465 SsrcMessageData data(ssrc);
466 Send(MSG_ISSTREAMMUTED, &data);
467 return data.result;
468}
469
470bool BaseChannel::AddRecvStream(const StreamParams& sp) {
471 StreamMessageData data(sp);
472 Send(MSG_ADDRECVSTREAM, &data);
473 return data.result;
474}
475
476bool BaseChannel::RemoveRecvStream(uint32 ssrc) {
477 SsrcMessageData data(ssrc);
478 Send(MSG_REMOVERECVSTREAM, &data);
479 return data.result;
480}
481
482bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
483 ContentAction action) {
484 SetContentData data(content, action);
485 Send(MSG_SETLOCALCONTENT, &data);
486 return data.result;
487}
488
489bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
490 ContentAction action) {
491 SetContentData data(content, action);
492 Send(MSG_SETREMOTECONTENT, &data);
493 return data.result;
494}
495
496bool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) {
497 SetBandwidthData data(max_bandwidth);
498 Send(MSG_SETMAXSENDBANDWIDTH, &data);
499 return data.result;
500}
501
502void BaseChannel::StartConnectionMonitor(int cms) {
503 socket_monitor_.reset(new SocketMonitor(transport_channel_,
504 worker_thread(),
505 talk_base::Thread::Current()));
506 socket_monitor_->SignalUpdate.connect(
507 this, &BaseChannel::OnConnectionMonitorUpdate);
508 socket_monitor_->Start(cms);
509}
510
511void BaseChannel::StopConnectionMonitor() {
512 if (socket_monitor_) {
513 socket_monitor_->Stop();
514 socket_monitor_.reset();
515 }
516}
517
518void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) {
519 if (rtcp_transport_channel_ != channel) {
520 if (rtcp_transport_channel_) {
521 session_->DestroyChannel(
522 content_name_, rtcp_transport_channel_->component());
523 }
524 rtcp_transport_channel_ = channel;
525 if (rtcp_transport_channel_) {
526 // TODO(juberti): Propagate this error code
527 VERIFY(SetDtlsSrtpCiphers(rtcp_transport_channel_, true));
528 rtcp_transport_channel_->SignalWritableState.connect(
529 this, &BaseChannel::OnWritableState);
530 rtcp_transport_channel_->SignalReadPacket.connect(
531 this, &BaseChannel::OnChannelRead);
532 rtcp_transport_channel_->SignalReadyToSend.connect(
533 this, &BaseChannel::OnReadyToSend);
534 }
535 }
536}
537
538bool BaseChannel::IsReadyToReceive() const {
539 // Receive data if we are enabled and have local content,
540 return enabled() && IsReceiveContentDirection(local_content_direction_);
541}
542
543bool BaseChannel::IsReadyToSend() const {
544 // Send outgoing data if we are enabled, have local and remote content,
545 // and we have had some form of connectivity.
546 return enabled() &&
547 IsReceiveContentDirection(remote_content_direction_) &&
548 IsSendContentDirection(local_content_direction_) &&
549 was_ever_writable();
550}
551
552bool BaseChannel::SendPacket(talk_base::Buffer* packet) {
553 return SendPacket(false, packet);
554}
555
556bool BaseChannel::SendRtcp(talk_base::Buffer* packet) {
557 return SendPacket(true, packet);
558}
559
560int BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt,
561 int value) {
562 switch (type) {
563 case ST_RTP: return transport_channel_->SetOption(opt, value);
564 case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value);
565 default: return -1;
566 }
567}
568
569void BaseChannel::OnWritableState(TransportChannel* channel) {
570 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
571 if (transport_channel_->writable()
572 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) {
573 ChannelWritable_w();
574 } else {
575 ChannelNotWritable_w();
576 }
577}
578
579void BaseChannel::OnChannelRead(TransportChannel* channel,
580 const char* data, size_t len, int flags) {
581 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
582 ASSERT(worker_thread_ == talk_base::Thread::Current());
583
584 // When using RTCP multiplexing we might get RTCP packets on the RTP
585 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP.
586 bool rtcp = PacketIsRtcp(channel, data, len);
587 talk_base::Buffer packet(data, len);
588 HandlePacket(rtcp, &packet);
589}
590
591void BaseChannel::OnReadyToSend(TransportChannel* channel) {
592 SetReadyToSend(channel, true);
593}
594
595void BaseChannel::SetReadyToSend(TransportChannel* channel, bool ready) {
596 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
597 if (channel == transport_channel_) {
598 rtp_ready_to_send_ = ready;
599 }
600 if (channel == rtcp_transport_channel_) {
601 rtcp_ready_to_send_ = ready;
602 }
603
604 if (!ready) {
605 // Notify the MediaChannel when either rtp or rtcp channel can't send.
606 media_channel_->OnReadyToSend(false);
607 } else if (rtp_ready_to_send_ &&
608 // In the case of rtcp mux |rtcp_transport_channel_| will be null.
609 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) {
610 // Notify the MediaChannel when both rtp and rtcp channel can send.
611 media_channel_->OnReadyToSend(true);
612 }
613}
614
615bool BaseChannel::PacketIsRtcp(const TransportChannel* channel,
616 const char* data, size_t len) {
617 return (channel == rtcp_transport_channel_ ||
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000618 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619}
620
621bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet) {
622 // Unless we're sending optimistically, we only allow packets through when we
623 // are completely writable.
624 if (!optimistic_data_send_ && !writable_) {
625 return false;
626 }
627
628 // SendPacket gets called from MediaEngine, typically on an encoder thread.
629 // If the thread is not our worker thread, we will post to our worker
630 // so that the real work happens on our worker. This avoids us having to
631 // synchronize access to all the pieces of the send path, including
632 // SRTP and the inner workings of the transport channels.
633 // The only downside is that we can't return a proper failure code if
634 // needed. Since UDP is unreliable anyway, this should be a non-issue.
635 if (talk_base::Thread::Current() != worker_thread_) {
636 // Avoid a copy by transferring the ownership of the packet data.
637 int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET;
638 PacketMessageData* data = new PacketMessageData;
639 packet->TransferTo(&data->packet);
640 worker_thread_->Post(this, message_id, data);
641 return true;
642 }
643
644 // Now that we are on the correct thread, ensure we have a place to send this
645 // packet before doing anything. (We might get RTCP packets that we don't
646 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
647 // transport.
648 TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ?
649 transport_channel_ : rtcp_transport_channel_;
650 if (!channel || (!optimistic_data_send_ && !channel->writable())) {
651 return false;
652 }
653
654 // Protect ourselves against crazy data.
655 if (!ValidPacket(rtcp, packet)) {
656 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
657 << PacketType(rtcp) << " packet: wrong size="
658 << packet->length();
659 return false;
660 }
661
662 // Signal to the media sink before protecting the packet.
663 {
664 talk_base::CritScope cs(&signal_send_packet_cs_);
665 SignalSendPacketPreCrypto(packet->data(), packet->length(), rtcp);
666 }
667
668 // Protect if needed.
669 if (srtp_filter_.IsActive()) {
670 bool res;
671 char* data = packet->data();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000672 int len = static_cast<int>(packet->length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 if (!rtcp) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000674 res = srtp_filter_.ProtectRtp(data, len,
675 static_cast<int>(packet->capacity()), &len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000676 if (!res) {
677 int seq_num = -1;
678 uint32 ssrc = 0;
679 GetRtpSeqNum(data, len, &seq_num);
680 GetRtpSsrc(data, len, &ssrc);
681 LOG(LS_ERROR) << "Failed to protect " << content_name_
682 << " RTP packet: size=" << len
683 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
684 return false;
685 }
686 } else {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000687 res = srtp_filter_.ProtectRtcp(data, len,
688 static_cast<int>(packet->capacity()),
689 &len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690 if (!res) {
691 int type = -1;
692 GetRtcpType(data, len, &type);
693 LOG(LS_ERROR) << "Failed to protect " << content_name_
694 << " RTCP packet: size=" << len << ", type=" << type;
695 return false;
696 }
697 }
698
699 // Update the length of the packet now that we've added the auth tag.
700 packet->SetLength(len);
701 } else if (secure_required_) {
702 // This is a double check for something that supposedly can't happen.
703 LOG(LS_ERROR) << "Can't send outgoing " << PacketType(rtcp)
704 << " packet when SRTP is inactive and crypto is required";
705
706 ASSERT(false);
707 return false;
708 }
709
710 // Signal to the media sink after protecting the packet.
711 {
712 talk_base::CritScope cs(&signal_send_packet_cs_);
713 SignalSendPacketPostCrypto(packet->data(), packet->length(), rtcp);
714 }
715
716 // Bon voyage.
717 int ret = channel->SendPacket(packet->data(), packet->length(),
718 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0);
719 if (ret != static_cast<int>(packet->length())) {
720 if (channel->GetError() == EWOULDBLOCK) {
721 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket.";
722 SetReadyToSend(channel, false);
723 }
724 return false;
725 }
726 return true;
727}
728
729bool BaseChannel::WantsPacket(bool rtcp, talk_base::Buffer* packet) {
730 // Protect ourselves against crazy data.
731 if (!ValidPacket(rtcp, packet)) {
732 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " "
733 << PacketType(rtcp) << " packet: wrong size="
734 << packet->length();
735 return false;
736 }
737 // If this channel is suppose to handle RTP data, that is determined by
738 // checking against ssrc filter. This is necessary to do it here to avoid
739 // double decryption.
740 if (ssrc_filter_.IsActive() &&
741 !ssrc_filter_.DemuxPacket(packet->data(), packet->length(), rtcp)) {
742 return false;
743 }
744
745 return true;
746}
747
748void BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) {
749 if (!WantsPacket(rtcp, packet)) {
750 return;
751 }
752
753 if (!has_received_packet_) {
754 has_received_packet_ = true;
755 signaling_thread()->Post(this, MSG_FIRSTPACKETRECEIVED);
756 }
757
758 // Signal to the media sink before unprotecting the packet.
759 {
760 talk_base::CritScope cs(&signal_recv_packet_cs_);
761 SignalRecvPacketPostCrypto(packet->data(), packet->length(), rtcp);
762 }
763
764 // Unprotect the packet, if needed.
765 if (srtp_filter_.IsActive()) {
766 char* data = packet->data();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000767 int len = static_cast<int>(packet->length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 bool res;
769 if (!rtcp) {
770 res = srtp_filter_.UnprotectRtp(data, len, &len);
771 if (!res) {
772 int seq_num = -1;
773 uint32 ssrc = 0;
774 GetRtpSeqNum(data, len, &seq_num);
775 GetRtpSsrc(data, len, &ssrc);
776 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
777 << " RTP packet: size=" << len
778 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
779 return;
780 }
781 } else {
782 res = srtp_filter_.UnprotectRtcp(data, len, &len);
783 if (!res) {
784 int type = -1;
785 GetRtcpType(data, len, &type);
786 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
787 << " RTCP packet: size=" << len << ", type=" << type;
788 return;
789 }
790 }
791
792 packet->SetLength(len);
793 } else if (secure_required_) {
794 // Our session description indicates that SRTP is required, but we got a
795 // packet before our SRTP filter is active. This means either that
796 // a) we got SRTP packets before we received the SDES keys, in which case
797 // we can't decrypt it anyway, or
798 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
799 // channels, so we haven't yet extracted keys, even if DTLS did complete
800 // on the channel that the packets are being sent on. It's really good
801 // practice to wait for both RTP and RTCP to be good to go before sending
802 // media, to prevent weird failure modes, so it's fine for us to just eat
803 // packets here. This is all sidestepped if RTCP mux is used anyway.
804 LOG(LS_WARNING) << "Can't process incoming " << PacketType(rtcp)
805 << " packet when SRTP is inactive and crypto is required";
806 return;
807 }
808
809 // Signal to the media sink after unprotecting the packet.
810 {
811 talk_base::CritScope cs(&signal_recv_packet_cs_);
812 SignalRecvPacketPreCrypto(packet->data(), packet->length(), rtcp);
813 }
814
815 // Push it down to the media channel.
816 if (!rtcp) {
817 media_channel_->OnPacketReceived(packet);
818 } else {
819 media_channel_->OnRtcpReceived(packet);
820 }
821}
822
823void BaseChannel::OnNewLocalDescription(
824 BaseSession* session, ContentAction action) {
825 const ContentInfo* content_info =
826 GetFirstContent(session->local_description());
827 const MediaContentDescription* content_desc =
828 GetContentDescription(content_info);
829 if (content_desc && content_info && !content_info->rejected &&
830 !SetLocalContent(content_desc, action)) {
831 LOG(LS_ERROR) << "Failure in SetLocalContent with action " << action;
832 session->SetError(BaseSession::ERROR_CONTENT);
833 }
834}
835
836void BaseChannel::OnNewRemoteDescription(
837 BaseSession* session, ContentAction action) {
838 const ContentInfo* content_info =
839 GetFirstContent(session->remote_description());
840 const MediaContentDescription* content_desc =
841 GetContentDescription(content_info);
842 if (content_desc && content_info && !content_info->rejected &&
843 !SetRemoteContent(content_desc, action)) {
844 LOG(LS_ERROR) << "Failure in SetRemoteContent with action " << action;
845 session->SetError(BaseSession::ERROR_CONTENT);
846 }
847}
848
849void BaseChannel::EnableMedia_w() {
850 ASSERT(worker_thread_ == talk_base::Thread::Current());
851 if (enabled_)
852 return;
853
854 LOG(LS_INFO) << "Channel enabled";
855 enabled_ = true;
856 ChangeState();
857}
858
859void BaseChannel::DisableMedia_w() {
860 ASSERT(worker_thread_ == talk_base::Thread::Current());
861 if (!enabled_)
862 return;
863
864 LOG(LS_INFO) << "Channel disabled";
865 enabled_ = false;
866 ChangeState();
867}
868
869bool BaseChannel::MuteStream_w(uint32 ssrc, bool mute) {
870 ASSERT(worker_thread_ == talk_base::Thread::Current());
871 bool ret = media_channel()->MuteStream(ssrc, mute);
872 if (ret) {
873 if (mute)
874 muted_streams_.insert(ssrc);
875 else
876 muted_streams_.erase(ssrc);
877 }
878 return ret;
879}
880
881bool BaseChannel::IsStreamMuted_w(uint32 ssrc) {
882 ASSERT(worker_thread_ == talk_base::Thread::Current());
883 return muted_streams_.find(ssrc) != muted_streams_.end();
884}
885
886void BaseChannel::ChannelWritable_w() {
887 ASSERT(worker_thread_ == talk_base::Thread::Current());
888 if (writable_)
889 return;
890
891 LOG(LS_INFO) << "Channel socket writable ("
892 << transport_channel_->content_name() << ", "
893 << transport_channel_->component() << ")"
894 << (was_ever_writable_ ? "" : " for the first time");
895
896 std::vector<ConnectionInfo> infos;
897 transport_channel_->GetStats(&infos);
898 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin();
899 it != infos.end(); ++it) {
900 if (it->best_connection) {
901 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString()
902 << "->" << it->remote_candidate.ToSensitiveString();
903 break;
904 }
905 }
906
907 // If we're doing DTLS-SRTP, now is the time.
908 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) {
909 if (!SetupDtlsSrtp(false)) {
910 LOG(LS_ERROR) << "Couldn't finish DTLS-SRTP on RTP channel";
911 SessionErrorMessageData data(BaseSession::ERROR_TRANSPORT);
912 // Sent synchronously.
913 signaling_thread()->Send(this, MSG_SESSION_ERROR, &data);
914 return;
915 }
916
917 if (rtcp_transport_channel_) {
918 if (!SetupDtlsSrtp(true)) {
919 LOG(LS_ERROR) << "Couldn't finish DTLS-SRTP on RTCP channel";
920 SessionErrorMessageData data(BaseSession::ERROR_TRANSPORT);
921 // Sent synchronously.
922 signaling_thread()->Send(this, MSG_SESSION_ERROR, &data);
923 return;
924 }
925 }
926 }
927
928 was_ever_writable_ = true;
929 writable_ = true;
930 ChangeState();
931}
932
933bool BaseChannel::SetDtlsSrtpCiphers(TransportChannel *tc, bool rtcp) {
934 std::vector<std::string> ciphers;
935 // We always use the default SRTP ciphers for RTCP, but we may use different
936 // ciphers for RTP depending on the media type.
937 if (!rtcp) {
938 GetSrtpCiphers(&ciphers);
939 } else {
940 GetSupportedDefaultCryptoSuites(&ciphers);
941 }
942 return tc->SetSrtpCiphers(ciphers);
943}
944
945bool BaseChannel::ShouldSetupDtlsSrtp() const {
946 return true;
947}
948
949// This function returns true if either DTLS-SRTP is not in use
950// *or* DTLS-SRTP is successfully set up.
951bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) {
952 bool ret = false;
953
954 TransportChannel *channel = rtcp_channel ?
955 rtcp_transport_channel_ : transport_channel_;
956
957 // No DTLS
958 if (!channel->IsDtlsActive())
959 return true;
960
961 std::string selected_cipher;
962
963 if (!channel->GetSrtpCipher(&selected_cipher)) {
964 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher";
965 return false;
966 }
967
968 LOG(LS_INFO) << "Installing keys from DTLS-SRTP on "
969 << content_name() << " "
970 << PacketType(rtcp_channel);
971
972 // OK, we're now doing DTLS (RFC 5764)
973 std::vector<unsigned char> dtls_buffer(SRTP_MASTER_KEY_KEY_LEN * 2 +
974 SRTP_MASTER_KEY_SALT_LEN * 2);
975
976 // RFC 5705 exporter using the RFC 5764 parameters
977 if (!channel->ExportKeyingMaterial(
978 kDtlsSrtpExporterLabel,
979 NULL, 0, false,
980 &dtls_buffer[0], dtls_buffer.size())) {
981 LOG(LS_WARNING) << "DTLS-SRTP key export failed";
982 ASSERT(false); // This should never happen
983 return false;
984 }
985
986 // Sync up the keys with the DTLS-SRTP interface
987 std::vector<unsigned char> client_write_key(SRTP_MASTER_KEY_KEY_LEN +
988 SRTP_MASTER_KEY_SALT_LEN);
989 std::vector<unsigned char> server_write_key(SRTP_MASTER_KEY_KEY_LEN +
990 SRTP_MASTER_KEY_SALT_LEN);
991 size_t offset = 0;
992 memcpy(&client_write_key[0], &dtls_buffer[offset],
993 SRTP_MASTER_KEY_KEY_LEN);
994 offset += SRTP_MASTER_KEY_KEY_LEN;
995 memcpy(&server_write_key[0], &dtls_buffer[offset],
996 SRTP_MASTER_KEY_KEY_LEN);
997 offset += SRTP_MASTER_KEY_KEY_LEN;
998 memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN],
999 &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
1000 offset += SRTP_MASTER_KEY_SALT_LEN;
1001 memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN],
1002 &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
1003
1004 std::vector<unsigned char> *send_key, *recv_key;
1005
1006 if (channel->GetRole() == ROLE_CONTROLLING) {
1007 send_key = &server_write_key;
1008 recv_key = &client_write_key;
1009 } else {
1010 send_key = &client_write_key;
1011 recv_key = &server_write_key;
1012 }
1013
1014 if (rtcp_channel) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001015 ret = srtp_filter_.SetRtcpParams(
1016 selected_cipher,
1017 &(*send_key)[0],
1018 static_cast<int>(send_key->size()),
1019 selected_cipher,
1020 &(*recv_key)[0],
1021 static_cast<int>(recv_key->size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 } else {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001023 ret = srtp_filter_.SetRtpParams(
1024 selected_cipher,
1025 &(*send_key)[0],
1026 static_cast<int>(send_key->size()),
1027 selected_cipher,
1028 &(*recv_key)[0],
1029 static_cast<int>(recv_key->size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001030 }
1031
1032 if (!ret)
1033 LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
1034 else
1035 dtls_keyed_ = true;
1036
1037 return ret;
1038}
1039
1040void BaseChannel::ChannelNotWritable_w() {
1041 ASSERT(worker_thread_ == talk_base::Thread::Current());
1042 if (!writable_)
1043 return;
1044
1045 LOG(LS_INFO) << "Channel socket not writable ("
1046 << transport_channel_->content_name() << ", "
1047 << transport_channel_->component() << ")";
1048 writable_ = false;
1049 ChangeState();
1050}
1051
1052// Sets the maximum video bandwidth for automatic bandwidth adjustment.
1053bool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) {
1054 return media_channel()->SetSendBandwidth(true, max_bandwidth);
1055}
1056
1057bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos,
1058 ContentAction action, ContentSource src) {
1059 bool ret = false;
1060 switch (action) {
1061 case CA_OFFER:
1062 ret = srtp_filter_.SetOffer(cryptos, src);
1063 break;
1064 case CA_PRANSWER:
1065 // If we're doing DTLS-SRTP, we don't want to update the filter
1066 // with an answer, because we already have SRTP parameters.
1067 if (transport_channel_->IsDtlsActive()) {
1068 LOG(LS_INFO) <<
1069 "Ignoring SDES answer parameters because we are using DTLS-SRTP";
1070 ret = true;
1071 } else {
1072 ret = srtp_filter_.SetProvisionalAnswer(cryptos, src);
1073 }
1074 break;
1075 case CA_ANSWER:
1076 // If we're doing DTLS-SRTP, we don't want to update the filter
1077 // with an answer, because we already have SRTP parameters.
1078 if (transport_channel_->IsDtlsActive()) {
1079 LOG(LS_INFO) <<
1080 "Ignoring SDES answer parameters because we are using DTLS-SRTP";
1081 ret = true;
1082 } else {
1083 ret = srtp_filter_.SetAnswer(cryptos, src);
1084 }
1085 break;
1086 case CA_UPDATE:
1087 // no crypto params.
1088 ret = true;
1089 break;
1090 default:
1091 break;
1092 }
1093 return ret;
1094}
1095
1096bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action,
1097 ContentSource src) {
1098 bool ret = false;
1099 switch (action) {
1100 case CA_OFFER:
1101 ret = rtcp_mux_filter_.SetOffer(enable, src);
1102 break;
1103 case CA_PRANSWER:
1104 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
1105 break;
1106 case CA_ANSWER:
1107 ret = rtcp_mux_filter_.SetAnswer(enable, src);
1108 if (ret && rtcp_mux_filter_.IsActive()) {
1109 // We activated RTCP mux, close down the RTCP transport.
1110 set_rtcp_transport_channel(NULL);
1111 }
1112 break;
1113 case CA_UPDATE:
1114 // No RTCP mux info.
1115 ret = true;
1116 default:
1117 break;
1118 }
1119 // |rtcp_mux_filter_| can be active if |action| is CA_PRANSWER or
1120 // CA_ANSWER, but we only want to tear down the RTCP transport channel if we
1121 // received a final answer.
1122 if (ret && rtcp_mux_filter_.IsActive()) {
1123 // If the RTP transport is already writable, then so are we.
1124 if (transport_channel_->writable()) {
1125 ChannelWritable_w();
1126 }
1127 }
1128
1129 return ret;
1130}
1131
1132bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
1133 ASSERT(worker_thread() == talk_base::Thread::Current());
1134 if (!media_channel()->AddRecvStream(sp))
1135 return false;
1136
1137 return ssrc_filter_.AddStream(sp);
1138}
1139
1140bool BaseChannel::RemoveRecvStream_w(uint32 ssrc) {
1141 ASSERT(worker_thread() == talk_base::Thread::Current());
1142 ssrc_filter_.RemoveStream(ssrc);
1143 return media_channel()->RemoveRecvStream(ssrc);
1144}
1145
1146bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
1147 ContentAction action) {
1148 if (!VERIFY(action == CA_OFFER || action == CA_ANSWER ||
1149 action == CA_PRANSWER || action == CA_UPDATE))
1150 return false;
1151
1152 // If this is an update, streams only contain streams that have changed.
1153 if (action == CA_UPDATE) {
1154 for (StreamParamsVec::const_iterator it = streams.begin();
1155 it != streams.end(); ++it) {
1156 StreamParams existing_stream;
1157 bool stream_exist = GetStreamByIds(local_streams_, it->groupid,
1158 it->id, &existing_stream);
1159 if (!stream_exist && it->has_ssrcs()) {
1160 if (media_channel()->AddSendStream(*it)) {
1161 local_streams_.push_back(*it);
1162 LOG(LS_INFO) << "Add send stream ssrc: " << it->first_ssrc();
1163 } else {
1164 LOG(LS_INFO) << "Failed to add send stream ssrc: "
1165 << it->first_ssrc();
1166 return false;
1167 }
1168 } else if (stream_exist && !it->has_ssrcs()) {
1169 if (!media_channel()->RemoveSendStream(existing_stream.first_ssrc())) {
1170 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
1171 << it->first_ssrc() << ".";
1172 return false;
1173 }
1174 RemoveStreamBySsrc(&local_streams_, existing_stream.first_ssrc());
1175 } else {
1176 LOG(LS_WARNING) << "Ignore unsupported stream update";
1177 }
1178 }
1179 return true;
1180 }
1181 // Else streams are all the streams we want to send.
1182
1183 // Check for streams that have been removed.
1184 bool ret = true;
1185 for (StreamParamsVec::const_iterator it = local_streams_.begin();
1186 it != local_streams_.end(); ++it) {
1187 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
1188 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
1189 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
1190 << it->first_ssrc() << ".";
1191 ret = false;
1192 }
1193 }
1194 }
1195 // Check for new streams.
1196 for (StreamParamsVec::const_iterator it = streams.begin();
1197 it != streams.end(); ++it) {
1198 if (!GetStreamBySsrc(local_streams_, it->first_ssrc(), NULL)) {
1199 if (media_channel()->AddSendStream(*it)) {
1200 LOG(LS_INFO) << "Add send ssrc: " << it->ssrcs[0];
1201 } else {
1202 LOG(LS_INFO) << "Failed to add send stream ssrc: " << it->first_ssrc();
1203 ret = false;
1204 }
1205 }
1206 }
1207 local_streams_ = streams;
1208 return ret;
1209}
1210
1211bool BaseChannel::UpdateRemoteStreams_w(
1212 const std::vector<StreamParams>& streams,
1213 ContentAction action) {
1214 if (!VERIFY(action == CA_OFFER || action == CA_ANSWER ||
1215 action == CA_PRANSWER || action == CA_UPDATE))
1216 return false;
1217
1218 // If this is an update, streams only contain streams that have changed.
1219 if (action == CA_UPDATE) {
1220 for (StreamParamsVec::const_iterator it = streams.begin();
1221 it != streams.end(); ++it) {
1222 StreamParams existing_stream;
1223 bool stream_exists = GetStreamByIds(remote_streams_, it->groupid,
1224 it->id, &existing_stream);
1225 if (!stream_exists && it->has_ssrcs()) {
1226 if (AddRecvStream_w(*it)) {
1227 remote_streams_.push_back(*it);
1228 LOG(LS_INFO) << "Add remote stream ssrc: " << it->first_ssrc();
1229 } else {
1230 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
1231 << it->first_ssrc();
1232 return false;
1233 }
1234 } else if (stream_exists && !it->has_ssrcs()) {
1235 if (!RemoveRecvStream_w(existing_stream.first_ssrc())) {
1236 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
1237 << it->first_ssrc() << ".";
1238 return false;
1239 }
1240 RemoveStreamBySsrc(&remote_streams_, existing_stream.first_ssrc());
1241 } else {
1242 LOG(LS_WARNING) << "Ignore unsupported stream update."
1243 << " Stream exists? " << stream_exists
1244 << " existing stream = " << existing_stream.ToString()
1245 << " new stream = " << it->ToString();
1246 }
1247 }
1248 return true;
1249 }
1250 // Else streams are all the streams we want to receive.
1251
1252 // Check for streams that have been removed.
1253 bool ret = true;
1254 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
1255 it != remote_streams_.end(); ++it) {
1256 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
1257 if (!RemoveRecvStream_w(it->first_ssrc())) {
1258 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
1259 << it->first_ssrc() << ".";
1260 ret = false;
1261 }
1262 }
1263 }
1264 // Check for new streams.
1265 for (StreamParamsVec::const_iterator it = streams.begin();
1266 it != streams.end(); ++it) {
1267 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc(), NULL)) {
1268 if (AddRecvStream_w(*it)) {
1269 LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
1270 } else {
1271 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
1272 << it->first_ssrc();
1273 ret = false;
1274 }
1275 }
1276 }
1277 remote_streams_ = streams;
1278 return ret;
1279}
1280
1281bool BaseChannel::SetBaseLocalContent_w(const MediaContentDescription* content,
1282 ContentAction action) {
1283 // Cache secure_required_ for belt and suspenders check on SendPacket
1284 secure_required_ = content->crypto_required();
1285 bool ret = UpdateLocalStreams_w(content->streams(), action);
1286 // Set local SRTP parameters (what we will encrypt with).
1287 ret &= SetSrtp_w(content->cryptos(), action, CS_LOCAL);
1288 // Set local RTCP mux parameters.
1289 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_LOCAL);
1290 // Set local RTP header extensions.
1291 if (content->rtp_header_extensions_set()) {
1292 ret &= media_channel()->SetRecvRtpHeaderExtensions(
1293 content->rtp_header_extensions());
1294 }
1295 set_local_content_direction(content->direction());
1296 return ret;
1297}
1298
1299bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content,
1300 ContentAction action) {
1301 bool ret = UpdateRemoteStreams_w(content->streams(), action);
1302 // Set remote SRTP parameters (what the other side will encrypt with).
1303 ret &= SetSrtp_w(content->cryptos(), action, CS_REMOTE);
1304 // Set remote RTCP mux parameters.
1305 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_REMOTE);
1306 // Set remote RTP header extensions.
1307 if (content->rtp_header_extensions_set()) {
1308 ret &= media_channel()->SetSendRtpHeaderExtensions(
1309 content->rtp_header_extensions());
1310 }
1311 if (content->bandwidth() != kAutoBandwidth) {
1312 ret &= media_channel()->SetSendBandwidth(false, content->bandwidth());
1313 }
1314 set_remote_content_direction(content->direction());
1315 return ret;
1316}
1317
1318void BaseChannel::OnMessage(talk_base::Message *pmsg) {
1319 switch (pmsg->message_id) {
1320 case MSG_ENABLE:
1321 EnableMedia_w();
1322 break;
1323 case MSG_DISABLE:
1324 DisableMedia_w();
1325 break;
1326 case MSG_MUTESTREAM: {
1327 MuteStreamData* data = static_cast<MuteStreamData*>(pmsg->pdata);
1328 data->result = MuteStream_w(data->ssrc, data->mute);
1329 break;
1330 }
1331 case MSG_ISSTREAMMUTED: {
1332 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
1333 data->result = IsStreamMuted_w(data->ssrc);
1334 break;
1335 }
1336 case MSG_SETLOCALCONTENT: {
1337 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
1338 data->result = SetLocalContent_w(data->content, data->action);
1339 break;
1340 }
1341 case MSG_SETREMOTECONTENT: {
1342 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
1343 data->result = SetRemoteContent_w(data->content, data->action);
1344 break;
1345 }
1346 case MSG_ADDRECVSTREAM: {
1347 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
1348 data->result = AddRecvStream_w(data->sp);
1349 break;
1350 }
1351 case MSG_REMOVERECVSTREAM: {
1352 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
1353 data->result = RemoveRecvStream_w(data->ssrc);
1354 break;
1355 }
1356 case MSG_SETMAXSENDBANDWIDTH: {
1357 SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata);
1358 data->result = SetMaxSendBandwidth_w(data->value);
1359 break;
1360 }
1361
1362 case MSG_RTPPACKET:
1363 case MSG_RTCPPACKET: {
1364 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata);
1365 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet);
1366 delete data; // because it is Posted
1367 break;
1368 }
1369 case MSG_FIRSTPACKETRECEIVED: {
1370 SignalFirstPacketReceived(this);
1371 break;
1372 }
1373 case MSG_SESSION_ERROR: {
1374 SessionErrorMessageData* data = static_cast<SessionErrorMessageData*>
1375 (pmsg->pdata);
1376 session_->SetError(data->error_);
1377 break;
1378 }
1379 }
1380}
1381
1382void BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) {
1383 worker_thread_->Send(this, id, pdata);
1384}
1385
1386void BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) {
1387 worker_thread_->Post(this, id, pdata);
1388}
1389
1390void BaseChannel::PostDelayed(int cmsDelay, uint32 id,
1391 talk_base::MessageData *pdata) {
1392 worker_thread_->PostDelayed(cmsDelay, this, id, pdata);
1393}
1394
1395void BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) {
1396 worker_thread_->Clear(this, id, removed);
1397}
1398
1399void BaseChannel::FlushRtcpMessages() {
1400 // Flush all remaining RTCP messages. This should only be called in
1401 // destructor.
1402 ASSERT(talk_base::Thread::Current() == worker_thread_);
1403 talk_base::MessageList rtcp_messages;
1404 Clear(MSG_RTCPPACKET, &rtcp_messages);
1405 for (talk_base::MessageList::iterator it = rtcp_messages.begin();
1406 it != rtcp_messages.end(); ++it) {
1407 Send(MSG_RTCPPACKET, it->pdata);
1408 }
1409}
1410
1411VoiceChannel::VoiceChannel(talk_base::Thread* thread,
1412 MediaEngineInterface* media_engine,
1413 VoiceMediaChannel* media_channel,
1414 BaseSession* session,
1415 const std::string& content_name,
1416 bool rtcp)
1417 : BaseChannel(thread, media_engine, media_channel, session, content_name,
1418 rtcp),
1419 received_media_(false) {
1420}
1421
1422VoiceChannel::~VoiceChannel() {
1423 StopAudioMonitor();
1424 StopMediaMonitor();
1425 // this can't be done in the base class, since it calls a virtual
1426 DisableMedia_w();
1427}
1428
1429bool VoiceChannel::Init() {
1430 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
1431 content_name(), "rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
1432 if (!BaseChannel::Init(session()->CreateChannel(
1433 content_name(), "rtp", ICE_CANDIDATE_COMPONENT_RTP),
1434 rtcp_channel)) {
1435 return false;
1436 }
1437 media_channel()->SignalMediaError.connect(
1438 this, &VoiceChannel::OnVoiceChannelError);
1439 srtp_filter()->SignalSrtpError.connect(
1440 this, &VoiceChannel::OnSrtpError);
1441 return true;
1442}
1443
1444bool VoiceChannel::SetRenderer(uint32 ssrc, AudioRenderer* renderer) {
1445 AudioRenderMessageData data(ssrc, renderer);
1446 Send(MSG_SETRENDERER, &data);
1447 return data.result;
1448}
1449
1450bool VoiceChannel::SetRingbackTone(const void* buf, int len) {
1451 SetRingbackToneMessageData data(buf, len);
1452 Send(MSG_SETRINGBACKTONE, &data);
1453 return data.result;
1454}
1455
1456// TODO(juberti): Handle early media the right way. We should get an explicit
1457// ringing message telling us to start playing local ringback, which we cancel
1458// if any early media actually arrives. For now, we do the opposite, which is
1459// to wait 1 second for early media, and start playing local ringback if none
1460// arrives.
1461void VoiceChannel::SetEarlyMedia(bool enable) {
1462 if (enable) {
1463 // Start the early media timeout
1464 PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT);
1465 } else {
1466 // Stop the timeout if currently going.
1467 Clear(MSG_EARLYMEDIATIMEOUT);
1468 }
1469}
1470
1471bool VoiceChannel::PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
1472 PlayRingbackToneMessageData data(ssrc, play, loop);
1473 Send(MSG_PLAYRINGBACKTONE, &data);
1474 return data.result;
1475}
1476
1477bool VoiceChannel::PressDTMF(int digit, bool playout) {
1478 int flags = DF_SEND;
1479 if (playout) {
1480 flags |= DF_PLAY;
1481 }
1482 int duration_ms = 160;
1483 return InsertDtmf(0, digit, duration_ms, flags);
1484}
1485
1486bool VoiceChannel::CanInsertDtmf() {
1487 BoolMessageData data(false);
1488 Send(MSG_CANINSERTDTMF, &data);
1489 return data.data();
1490}
1491
1492bool VoiceChannel::InsertDtmf(uint32 ssrc, int event_code, int duration,
1493 int flags) {
1494 DtmfMessageData data(ssrc, event_code, duration, flags);
1495 Send(MSG_INSERTDTMF, &data);
1496 return data.result;
1497}
1498
1499bool VoiceChannel::SetOutputScaling(uint32 ssrc, double left, double right) {
1500 ScaleVolumeMessageData data(ssrc, left, right);
1501 Send(MSG_SCALEVOLUME, &data);
1502 return data.result;
1503}
1504bool VoiceChannel::GetStats(VoiceMediaInfo* stats) {
1505 VoiceStatsMessageData data(stats);
1506 Send(MSG_GETSTATS, &data);
1507 return data.result;
1508}
1509
1510void VoiceChannel::StartMediaMonitor(int cms) {
1511 media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(),
1512 talk_base::Thread::Current()));
1513 media_monitor_->SignalUpdate.connect(
1514 this, &VoiceChannel::OnMediaMonitorUpdate);
1515 media_monitor_->Start(cms);
1516}
1517
1518void VoiceChannel::StopMediaMonitor() {
1519 if (media_monitor_) {
1520 media_monitor_->Stop();
1521 media_monitor_->SignalUpdate.disconnect(this);
1522 media_monitor_.reset();
1523 }
1524}
1525
1526void VoiceChannel::StartAudioMonitor(int cms) {
1527 audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current()));
1528 audio_monitor_
1529 ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate);
1530 audio_monitor_->Start(cms);
1531}
1532
1533void VoiceChannel::StopAudioMonitor() {
1534 if (audio_monitor_) {
1535 audio_monitor_->Stop();
1536 audio_monitor_.reset();
1537 }
1538}
1539
1540bool VoiceChannel::IsAudioMonitorRunning() const {
1541 return (audio_monitor_.get() != NULL);
1542}
1543
1544void VoiceChannel::StartTypingMonitor(const TypingMonitorOptions& settings) {
1545 typing_monitor_.reset(new TypingMonitor(this, worker_thread(), settings));
1546 SignalAutoMuted.repeat(typing_monitor_->SignalMuted);
1547}
1548
1549void VoiceChannel::StopTypingMonitor() {
1550 typing_monitor_.reset();
1551}
1552
1553bool VoiceChannel::IsTypingMonitorRunning() const {
1554 return typing_monitor_;
1555}
1556
1557bool VoiceChannel::MuteStream_w(uint32 ssrc, bool mute) {
1558 bool ret = BaseChannel::MuteStream_w(ssrc, mute);
1559 if (typing_monitor_ && mute)
1560 typing_monitor_->OnChannelMuted();
1561 return ret;
1562}
1563
1564int VoiceChannel::GetInputLevel_w() {
1565 return media_engine()->GetInputLevel();
1566}
1567
1568int VoiceChannel::GetOutputLevel_w() {
1569 return media_channel()->GetOutputLevel();
1570}
1571
1572void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) {
1573 media_channel()->GetActiveStreams(actives);
1574}
1575
1576void VoiceChannel::OnChannelRead(TransportChannel* channel,
1577 const char* data, size_t len, int flags) {
1578 BaseChannel::OnChannelRead(channel, data, len, flags);
1579
1580 // Set a flag when we've received an RTP packet. If we're waiting for early
1581 // media, this will disable the timeout.
1582 if (!received_media_ && !PacketIsRtcp(channel, data, len)) {
1583 received_media_ = true;
1584 }
1585}
1586
1587void VoiceChannel::ChangeState() {
1588 // Render incoming data if we're the active call, and we have the local
1589 // content. We receive data on the default channel and multiplexed streams.
1590 bool recv = IsReadyToReceive();
1591 if (!media_channel()->SetPlayout(recv)) {
1592 SendLastMediaError();
1593 }
1594
1595 // Send outgoing data if we're the active call, we have the remote content,
1596 // and we have had some form of connectivity.
1597 bool send = IsReadyToSend();
1598 SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING;
1599 if (!media_channel()->SetSend(send_flag)) {
1600 LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel";
1601 SendLastMediaError();
1602 }
1603
1604 LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
1605}
1606
1607const ContentInfo* VoiceChannel::GetFirstContent(
1608 const SessionDescription* sdesc) {
1609 return GetFirstAudioContent(sdesc);
1610}
1611
1612bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
1613 ContentAction action) {
1614 ASSERT(worker_thread() == talk_base::Thread::Current());
1615 LOG(LS_INFO) << "Setting local voice description";
1616
1617 const AudioContentDescription* audio =
1618 static_cast<const AudioContentDescription*>(content);
1619 ASSERT(audio != NULL);
1620 if (!audio) return false;
1621
1622 bool ret = SetBaseLocalContent_w(content, action);
1623 // Set local audio codecs (what we want to receive).
1624 // TODO(whyuan): Change action != CA_UPDATE to !audio->partial() when partial
1625 // is set properly.
1626 if (action != CA_UPDATE || audio->has_codecs()) {
1627 ret &= media_channel()->SetRecvCodecs(audio->codecs());
1628 }
1629
1630 // If everything worked, see if we can start receiving.
1631 if (ret) {
1632 ChangeState();
1633 } else {
1634 LOG(LS_WARNING) << "Failed to set local voice description";
1635 }
1636 return ret;
1637}
1638
1639bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
1640 ContentAction action) {
1641 ASSERT(worker_thread() == talk_base::Thread::Current());
1642 LOG(LS_INFO) << "Setting remote voice description";
1643
1644 const AudioContentDescription* audio =
1645 static_cast<const AudioContentDescription*>(content);
1646 ASSERT(audio != NULL);
1647 if (!audio) return false;
1648
1649 bool ret = true;
1650 // Set remote video codecs (what the other side wants to receive).
1651 if (action != CA_UPDATE || audio->has_codecs()) {
1652 ret &= media_channel()->SetSendCodecs(audio->codecs());
1653 }
1654
1655 ret &= SetBaseRemoteContent_w(content, action);
1656
1657 if (action != CA_UPDATE) {
1658 // Tweak our audio processing settings, if needed.
1659 AudioOptions audio_options;
1660 if (!media_channel()->GetOptions(&audio_options)) {
1661 LOG(LS_WARNING) << "Can not set audio options from on remote content.";
1662 } else {
1663 if (audio->conference_mode()) {
1664 audio_options.conference_mode.Set(true);
1665 }
1666 if (audio->agc_minus_10db()) {
1667 audio_options.adjust_agc_delta.Set(kAgcMinus10db);
1668 }
1669 if (!media_channel()->SetOptions(audio_options)) {
1670 // Log an error on failure, but don't abort the call.
1671 LOG(LS_ERROR) << "Failed to set voice channel options";
1672 }
1673 }
1674 }
1675
1676 // If everything worked, see if we can start sending.
1677 if (ret) {
1678 ChangeState();
1679 } else {
1680 LOG(LS_WARNING) << "Failed to set remote voice description";
1681 }
1682 return ret;
1683}
1684
1685bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) {
1686 ASSERT(worker_thread() == talk_base::Thread::Current());
1687 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len);
1688}
1689
1690bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) {
1691 ASSERT(worker_thread() == talk_base::Thread::Current());
1692 if (play) {
1693 LOG(LS_INFO) << "Playing ringback tone, loop=" << loop;
1694 } else {
1695 LOG(LS_INFO) << "Stopping ringback tone";
1696 }
1697 return media_channel()->PlayRingbackTone(ssrc, play, loop);
1698}
1699
1700void VoiceChannel::HandleEarlyMediaTimeout() {
1701 // This occurs on the main thread, not the worker thread.
1702 if (!received_media_) {
1703 LOG(LS_INFO) << "No early media received before timeout";
1704 SignalEarlyMediaTimeout(this);
1705 }
1706}
1707
1708bool VoiceChannel::CanInsertDtmf_w() {
1709 return media_channel()->CanInsertDtmf();
1710}
1711
1712bool VoiceChannel::InsertDtmf_w(uint32 ssrc, int event, int duration,
1713 int flags) {
1714 if (!enabled()) {
1715 return false;
1716 }
1717
1718 return media_channel()->InsertDtmf(ssrc, event, duration, flags);
1719}
1720
1721bool VoiceChannel::SetOutputScaling_w(uint32 ssrc, double left, double right) {
1722 return media_channel()->SetOutputScaling(ssrc, left, right);
1723}
1724
1725bool VoiceChannel::GetStats_w(VoiceMediaInfo* stats) {
1726 return media_channel()->GetStats(stats);
1727}
1728
1729bool VoiceChannel::SetChannelOptions(const AudioOptions& options) {
1730 AudioOptionsMessageData data(options);
1731 Send(MSG_SETCHANNELOPTIONS, &data);
1732 return data.result;
1733}
1734
1735bool VoiceChannel::SetChannelOptions_w(const AudioOptions& options) {
1736 return media_channel()->SetOptions(options);
1737}
1738
1739bool VoiceChannel::SetRenderer_w(uint32 ssrc, AudioRenderer* renderer) {
1740 return media_channel()->SetRenderer(ssrc, renderer);
1741}
1742
1743void VoiceChannel::OnMessage(talk_base::Message *pmsg) {
1744 switch (pmsg->message_id) {
1745 case MSG_SETRINGBACKTONE: {
1746 SetRingbackToneMessageData* data =
1747 static_cast<SetRingbackToneMessageData*>(pmsg->pdata);
1748 data->result = SetRingbackTone_w(data->buf, data->len);
1749 break;
1750 }
1751 case MSG_PLAYRINGBACKTONE: {
1752 PlayRingbackToneMessageData* data =
1753 static_cast<PlayRingbackToneMessageData*>(pmsg->pdata);
1754 data->result = PlayRingbackTone_w(data->ssrc, data->play, data->loop);
1755 break;
1756 }
1757 case MSG_EARLYMEDIATIMEOUT:
1758 HandleEarlyMediaTimeout();
1759 break;
1760 case MSG_CANINSERTDTMF: {
1761 BoolMessageData* data =
1762 static_cast<BoolMessageData*>(pmsg->pdata);
1763 data->data() = CanInsertDtmf_w();
1764 break;
1765 }
1766 case MSG_INSERTDTMF: {
1767 DtmfMessageData* data =
1768 static_cast<DtmfMessageData*>(pmsg->pdata);
1769 data->result = InsertDtmf_w(data->ssrc, data->event, data->duration,
1770 data->flags);
1771 break;
1772 }
1773 case MSG_SCALEVOLUME: {
1774 ScaleVolumeMessageData* data =
1775 static_cast<ScaleVolumeMessageData*>(pmsg->pdata);
1776 data->result = SetOutputScaling_w(data->ssrc, data->left, data->right);
1777 break;
1778 }
1779 case MSG_GETSTATS: {
1780 VoiceStatsMessageData* data =
1781 static_cast<VoiceStatsMessageData*>(pmsg->pdata);
1782 data->result = GetStats_w(data->stats);
1783 break;
1784 }
1785 case MSG_CHANNEL_ERROR: {
1786 VoiceChannelErrorMessageData* data =
1787 static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata);
1788 SignalMediaError(this, data->ssrc, data->error);
1789 delete data;
1790 break;
1791 }
1792 case MSG_SETCHANNELOPTIONS: {
1793 AudioOptionsMessageData* data =
1794 static_cast<AudioOptionsMessageData*>(pmsg->pdata);
1795 data->result = SetChannelOptions_w(data->options);
1796 break;
1797 }
1798 case MSG_SETRENDERER: {
1799 AudioRenderMessageData* data =
1800 static_cast<AudioRenderMessageData*>(pmsg->pdata);
1801 data->result = SetRenderer_w(data->ssrc, data->renderer);
1802 break;
1803 }
1804 default:
1805 BaseChannel::OnMessage(pmsg);
1806 break;
1807 }
1808}
1809
1810void VoiceChannel::OnConnectionMonitorUpdate(
1811 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
1812 SignalConnectionMonitor(this, infos);
1813}
1814
1815void VoiceChannel::OnMediaMonitorUpdate(
1816 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) {
1817 ASSERT(media_channel == this->media_channel());
1818 SignalMediaMonitor(this, info);
1819}
1820
1821void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor,
1822 const AudioInfo& info) {
1823 SignalAudioMonitor(this, info);
1824}
1825
1826void VoiceChannel::OnVoiceChannelError(
1827 uint32 ssrc, VoiceMediaChannel::Error err) {
1828 VoiceChannelErrorMessageData* data = new VoiceChannelErrorMessageData(
1829 ssrc, err);
1830 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
1831}
1832
1833void VoiceChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
1834 SrtpFilter::Error error) {
1835 switch (error) {
1836 case SrtpFilter::ERROR_FAIL:
1837 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1838 VoiceMediaChannel::ERROR_REC_SRTP_ERROR :
1839 VoiceMediaChannel::ERROR_PLAY_SRTP_ERROR);
1840 break;
1841 case SrtpFilter::ERROR_AUTH:
1842 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1843 VoiceMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
1844 VoiceMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
1845 break;
1846 case SrtpFilter::ERROR_REPLAY:
1847 // Only receving channel should have this error.
1848 ASSERT(mode == SrtpFilter::UNPROTECT);
1849 OnVoiceChannelError(ssrc, VoiceMediaChannel::ERROR_PLAY_SRTP_REPLAY);
1850 break;
1851 default:
1852 break;
1853 }
1854}
1855
1856void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
1857 GetSupportedAudioCryptoSuites(ciphers);
1858}
1859
1860VideoChannel::VideoChannel(talk_base::Thread* thread,
1861 MediaEngineInterface* media_engine,
1862 VideoMediaChannel* media_channel,
1863 BaseSession* session,
1864 const std::string& content_name,
1865 bool rtcp,
1866 VoiceChannel* voice_channel)
1867 : BaseChannel(thread, media_engine, media_channel, session, content_name,
1868 rtcp),
1869 voice_channel_(voice_channel),
1870 renderer_(NULL),
1871 screencapture_factory_(CreateScreenCapturerFactory()),
1872 previous_we_(talk_base::WE_CLOSE) {
1873}
1874
1875bool VideoChannel::Init() {
1876 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
1877 content_name(), "video_rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
1878 if (!BaseChannel::Init(session()->CreateChannel(
1879 content_name(), "video_rtp", ICE_CANDIDATE_COMPONENT_RTP),
1880 rtcp_channel)) {
1881 return false;
1882 }
1883 media_channel()->SignalMediaError.connect(
1884 this, &VideoChannel::OnVideoChannelError);
1885 srtp_filter()->SignalSrtpError.connect(
1886 this, &VideoChannel::OnSrtpError);
1887 return true;
1888}
1889
1890void VoiceChannel::SendLastMediaError() {
1891 uint32 ssrc;
1892 VoiceMediaChannel::Error error;
1893 media_channel()->GetLastMediaError(&ssrc, &error);
1894 SignalMediaError(this, ssrc, error);
1895}
1896
1897VideoChannel::~VideoChannel() {
1898 std::vector<uint32> screencast_ssrcs;
1899 ScreencastMap::iterator iter;
1900 while (!screencast_capturers_.empty()) {
1901 if (!RemoveScreencast(screencast_capturers_.begin()->first)) {
1902 LOG(LS_ERROR) << "Unable to delete screencast with ssrc "
1903 << screencast_capturers_.begin()->first;
1904 ASSERT(false);
1905 break;
1906 }
1907 }
1908
1909 StopMediaMonitor();
1910 // this can't be done in the base class, since it calls a virtual
1911 DisableMedia_w();
1912}
1913
1914bool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
1915 VideoRenderMessageData data(ssrc, renderer);
1916 Send(MSG_SETRENDERER, &data);
1917 return true;
1918}
1919
1920bool VideoChannel::ApplyViewRequest(const ViewRequest& request) {
1921 ViewRequestMessageData data(request);
1922 Send(MSG_HANDLEVIEWREQUEST, &data);
1923 return data.result;
1924}
1925
1926VideoCapturer* VideoChannel::AddScreencast(
1927 uint32 ssrc, const ScreencastId& id) {
1928 AddScreencastMessageData data(ssrc, id);
1929 Send(MSG_ADDSCREENCAST, &data);
1930 return data.result;
1931}
1932
1933bool VideoChannel::SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
1934 SetCapturerMessageData data(ssrc, capturer);
1935 Send(MSG_SETCAPTURER, &data);
1936 return data.result;
1937}
1938
1939bool VideoChannel::RemoveScreencast(uint32 ssrc) {
1940 RemoveScreencastMessageData data(ssrc);
1941 Send(MSG_REMOVESCREENCAST, &data);
1942 return data.result;
1943}
1944
1945bool VideoChannel::IsScreencasting() {
1946 IsScreencastingMessageData data;
1947 Send(MSG_ISSCREENCASTING, &data);
1948 return data.result;
1949}
1950
1951int VideoChannel::ScreencastFps(uint32 ssrc) {
1952 ScreencastFpsMessageData data(ssrc);
1953 Send(MSG_SCREENCASTFPS, &data);
1954 return data.result;
1955}
1956
1957bool VideoChannel::SendIntraFrame() {
1958 Send(MSG_SENDINTRAFRAME);
1959 return true;
1960}
1961
1962bool VideoChannel::RequestIntraFrame() {
1963 Send(MSG_REQUESTINTRAFRAME);
1964 return true;
1965}
1966
1967void VideoChannel::SetScreenCaptureFactory(
1968 ScreenCapturerFactory* screencapture_factory) {
1969 SetScreenCaptureFactoryMessageData data(screencapture_factory);
1970 Send(MSG_SETSCREENCASTFACTORY, &data);
1971}
1972
1973void VideoChannel::ChangeState() {
1974 // Render incoming data if we're the active call, and we have the local
1975 // content. We receive data on the default channel and multiplexed streams.
1976 bool recv = IsReadyToReceive();
1977 if (!media_channel()->SetRender(recv)) {
1978 LOG(LS_ERROR) << "Failed to SetRender on video channel";
1979 // TODO(gangji): Report error back to server.
1980 }
1981
1982 // Send outgoing data if we're the active call, we have the remote content,
1983 // and we have had some form of connectivity.
1984 bool send = IsReadyToSend();
1985 if (!media_channel()->SetSend(send)) {
1986 LOG(LS_ERROR) << "Failed to SetSend on video channel";
1987 // TODO(gangji): Report error back to server.
1988 }
1989
1990 LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send;
1991}
1992
1993bool VideoChannel::GetStats(VideoMediaInfo* stats) {
1994 VideoStatsMessageData data(stats);
1995 Send(MSG_GETSTATS, &data);
1996 return data.result;
1997}
1998
1999void VideoChannel::StartMediaMonitor(int cms) {
2000 media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(),
2001 talk_base::Thread::Current()));
2002 media_monitor_->SignalUpdate.connect(
2003 this, &VideoChannel::OnMediaMonitorUpdate);
2004 media_monitor_->Start(cms);
2005}
2006
2007void VideoChannel::StopMediaMonitor() {
2008 if (media_monitor_) {
2009 media_monitor_->Stop();
2010 media_monitor_.reset();
2011 }
2012}
2013
2014const ContentInfo* VideoChannel::GetFirstContent(
2015 const SessionDescription* sdesc) {
2016 return GetFirstVideoContent(sdesc);
2017}
2018
2019bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
2020 ContentAction action) {
2021 ASSERT(worker_thread() == talk_base::Thread::Current());
2022 LOG(LS_INFO) << "Setting local video description";
2023
2024 const VideoContentDescription* video =
2025 static_cast<const VideoContentDescription*>(content);
2026 ASSERT(video != NULL);
2027 if (!video) return false;
2028
2029 bool ret = SetBaseLocalContent_w(content, action);
2030 // Set local video codecs (what we want to receive).
2031 if (action != CA_UPDATE || video->has_codecs()) {
2032 ret &= media_channel()->SetRecvCodecs(video->codecs());
2033 }
2034
2035 if (action != CA_UPDATE) {
2036 VideoOptions video_options;
2037 media_channel()->GetOptions(&video_options);
2038 video_options.buffered_mode_latency.Set(video->buffered_mode_latency());
2039
2040 if (!media_channel()->SetOptions(video_options)) {
2041 // Log an error on failure, but don't abort the call.
2042 LOG(LS_ERROR) << "Failed to set video channel options";
2043 }
2044 }
2045
2046 // If everything worked, see if we can start receiving.
2047 if (ret) {
2048 ChangeState();
2049 } else {
2050 LOG(LS_WARNING) << "Failed to set local video description";
2051 }
2052 return ret;
2053}
2054
2055bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
2056 ContentAction action) {
2057 ASSERT(worker_thread() == talk_base::Thread::Current());
2058 LOG(LS_INFO) << "Setting remote video description";
2059
2060 const VideoContentDescription* video =
2061 static_cast<const VideoContentDescription*>(content);
2062 ASSERT(video != NULL);
2063 if (!video) return false;
2064
2065 bool ret = true;
2066 // Set remote video codecs (what the other side wants to receive).
2067 if (action != CA_UPDATE || video->has_codecs()) {
2068 ret &= media_channel()->SetSendCodecs(video->codecs());
2069 }
2070
2071 ret &= SetBaseRemoteContent_w(content, action);
2072
2073 if (action != CA_UPDATE) {
2074 // Tweak our video processing settings, if needed.
2075 VideoOptions video_options;
2076 media_channel()->GetOptions(&video_options);
2077 video_options.conference_mode.Set(video->conference_mode());
2078 video_options.buffered_mode_latency.Set(video->buffered_mode_latency());
2079
2080 if (!media_channel()->SetOptions(video_options)) {
2081 // Log an error on failure, but don't abort the call.
2082 LOG(LS_ERROR) << "Failed to set video channel options";
2083 }
2084 }
2085
2086 // If everything worked, see if we can start sending.
2087 if (ret) {
2088 ChangeState();
2089 } else {
2090 LOG(LS_WARNING) << "Failed to set remote video description";
2091 }
2092 return ret;
2093}
2094
2095bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) {
2096 bool ret = true;
2097 // Set the send format for each of the local streams. If the view request
2098 // does not contain a local stream, set its send format to 0x0, which will
2099 // drop all frames.
2100 for (std::vector<StreamParams>::const_iterator it = local_streams().begin();
2101 it != local_streams().end(); ++it) {
2102 VideoFormat format(0, 0, 0, cricket::FOURCC_I420);
2103 StaticVideoViews::const_iterator view;
2104 for (view = request.static_video_views.begin();
2105 view != request.static_video_views.end(); ++view) {
2106 if (view->selector.Matches(*it)) {
2107 format.width = view->width;
2108 format.height = view->height;
2109 format.interval = cricket::VideoFormat::FpsToInterval(view->framerate);
2110 break;
2111 }
2112 }
2113
2114 ret &= media_channel()->SetSendStreamFormat(it->first_ssrc(), format);
2115 }
2116
2117 // Check if the view request has invalid streams.
2118 for (StaticVideoViews::const_iterator it = request.static_video_views.begin();
2119 it != request.static_video_views.end(); ++it) {
2120 if (!GetStream(local_streams(), it->selector, NULL)) {
2121 LOG(LS_WARNING) << "View request for ("
2122 << it->selector.ssrc << ", '"
2123 << it->selector.groupid << "', '"
2124 << it->selector.streamid << "'"
2125 << ") is not in the local streams.";
2126 }
2127 }
2128
2129 return ret;
2130}
2131
2132void VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) {
2133 media_channel()->SetRenderer(ssrc, renderer);
2134}
2135
2136VideoCapturer* VideoChannel::AddScreencast_w(
2137 uint32 ssrc, const ScreencastId& id) {
2138 if (screencast_capturers_.find(ssrc) != screencast_capturers_.end()) {
2139 return NULL;
2140 }
2141 VideoCapturer* screen_capturer =
2142 screencapture_factory_->CreateScreenCapturer(id);
2143 if (!screen_capturer) {
2144 return NULL;
2145 }
2146 screen_capturer->SignalStateChange.connect(this,
2147 &VideoChannel::OnStateChange);
2148 screencast_capturers_[ssrc] = screen_capturer;
2149 return screen_capturer;
2150}
2151
2152bool VideoChannel::SetCapturer_w(uint32 ssrc, VideoCapturer* capturer) {
2153 return media_channel()->SetCapturer(ssrc, capturer);
2154}
2155
2156bool VideoChannel::RemoveScreencast_w(uint32 ssrc) {
2157 ScreencastMap::iterator iter = screencast_capturers_.find(ssrc);
2158 if (iter == screencast_capturers_.end()) {
2159 return false;
2160 }
2161 // Clean up VideoCapturer.
2162 delete iter->second;
2163 screencast_capturers_.erase(iter);
2164 return true;
2165}
2166
2167bool VideoChannel::IsScreencasting_w() const {
2168 return !screencast_capturers_.empty();
2169}
2170
2171int VideoChannel::ScreencastFps_w(uint32 ssrc) const {
2172 ScreencastMap::const_iterator iter = screencast_capturers_.find(ssrc);
2173 if (iter == screencast_capturers_.end()) {
2174 return 0;
2175 }
2176 VideoCapturer* capturer = iter->second;
2177 const VideoFormat* video_format = capturer->GetCaptureFormat();
2178 return VideoFormat::IntervalToFps(video_format->interval);
2179}
2180
2181void VideoChannel::SetScreenCaptureFactory_w(
2182 ScreenCapturerFactory* screencapture_factory) {
2183 if (screencapture_factory == NULL) {
2184 screencapture_factory_.reset(CreateScreenCapturerFactory());
2185 } else {
2186 screencapture_factory_.reset(screencapture_factory);
2187 }
2188}
2189
2190bool VideoChannel::GetStats_w(VideoMediaInfo* stats) {
2191 return media_channel()->GetStats(stats);
2192}
2193
2194void VideoChannel::OnScreencastWindowEvent_s(uint32 ssrc,
2195 talk_base::WindowEvent we) {
2196 ASSERT(signaling_thread() == talk_base::Thread::Current());
2197 SignalScreencastWindowEvent(ssrc, we);
2198}
2199
2200bool VideoChannel::SetChannelOptions(const VideoOptions &options) {
2201 VideoOptionsMessageData data(options);
2202 Send(MSG_SETCHANNELOPTIONS, &data);
2203 return data.result;
2204}
2205
2206bool VideoChannel::SetChannelOptions_w(const VideoOptions &options) {
2207 return media_channel()->SetOptions(options);
2208}
2209
2210void VideoChannel::OnMessage(talk_base::Message *pmsg) {
2211 switch (pmsg->message_id) {
2212 case MSG_SETRENDERER: {
2213 const VideoRenderMessageData* data =
2214 static_cast<VideoRenderMessageData*>(pmsg->pdata);
2215 SetRenderer_w(data->ssrc, data->renderer);
2216 break;
2217 }
2218 case MSG_ADDSCREENCAST: {
2219 AddScreencastMessageData* data =
2220 static_cast<AddScreencastMessageData*>(pmsg->pdata);
2221 data->result = AddScreencast_w(data->ssrc, data->window_id);
2222 break;
2223 }
2224 case MSG_SETCAPTURER: {
2225 SetCapturerMessageData* data =
2226 static_cast<SetCapturerMessageData*>(pmsg->pdata);
2227 data->result = SetCapturer_w(data->ssrc, data->capturer);
2228 break;
2229 }
2230 case MSG_REMOVESCREENCAST: {
2231 RemoveScreencastMessageData* data =
2232 static_cast<RemoveScreencastMessageData*>(pmsg->pdata);
2233 data->result = RemoveScreencast_w(data->ssrc);
2234 break;
2235 }
2236 case MSG_SCREENCASTWINDOWEVENT: {
2237 const ScreencastEventMessageData* data =
2238 static_cast<ScreencastEventMessageData*>(pmsg->pdata);
2239 OnScreencastWindowEvent_s(data->ssrc, data->event);
2240 delete data;
2241 break;
2242 }
2243 case MSG_ISSCREENCASTING: {
2244 IsScreencastingMessageData* data =
2245 static_cast<IsScreencastingMessageData*>(pmsg->pdata);
2246 data->result = IsScreencasting_w();
2247 break;
2248 }
2249 case MSG_SCREENCASTFPS: {
2250 ScreencastFpsMessageData* data =
2251 static_cast<ScreencastFpsMessageData*>(pmsg->pdata);
2252 data->result = ScreencastFps_w(data->ssrc);
2253 break;
2254 }
2255 case MSG_SENDINTRAFRAME: {
2256 SendIntraFrame_w();
2257 break;
2258 }
2259 case MSG_REQUESTINTRAFRAME: {
2260 RequestIntraFrame_w();
2261 break;
2262 }
2263 case MSG_SETCHANNELOPTIONS: {
2264 VideoOptionsMessageData* data =
2265 static_cast<VideoOptionsMessageData*>(pmsg->pdata);
2266 data->result = SetChannelOptions_w(data->options);
2267 break;
2268 }
2269 case MSG_CHANNEL_ERROR: {
2270 const VideoChannelErrorMessageData* data =
2271 static_cast<VideoChannelErrorMessageData*>(pmsg->pdata);
2272 SignalMediaError(this, data->ssrc, data->error);
2273 delete data;
2274 break;
2275 }
2276 case MSG_HANDLEVIEWREQUEST: {
2277 ViewRequestMessageData* data =
2278 static_cast<ViewRequestMessageData*>(pmsg->pdata);
2279 data->result = ApplyViewRequest_w(data->request);
2280 break;
2281 }
2282 case MSG_SETSCREENCASTFACTORY: {
2283 SetScreenCaptureFactoryMessageData* data =
2284 static_cast<SetScreenCaptureFactoryMessageData*>(pmsg->pdata);
2285 SetScreenCaptureFactory_w(data->screencapture_factory);
2286 }
2287 case MSG_GETSTATS: {
2288 VideoStatsMessageData* data =
2289 static_cast<VideoStatsMessageData*>(pmsg->pdata);
2290 data->result = GetStats_w(data->stats);
2291 break;
2292 }
2293 default:
2294 BaseChannel::OnMessage(pmsg);
2295 break;
2296 }
2297}
2298
2299void VideoChannel::OnConnectionMonitorUpdate(
2300 SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) {
2301 SignalConnectionMonitor(this, infos);
2302}
2303
2304// TODO(pthatcher): Look into removing duplicate code between
2305// audio, video, and data, perhaps by using templates.
2306void VideoChannel::OnMediaMonitorUpdate(
2307 VideoMediaChannel* media_channel, const VideoMediaInfo &info) {
2308 ASSERT(media_channel == this->media_channel());
2309 SignalMediaMonitor(this, info);
2310}
2311
2312void VideoChannel::OnScreencastWindowEvent(uint32 ssrc,
2313 talk_base::WindowEvent event) {
2314 ScreencastEventMessageData* pdata =
2315 new ScreencastEventMessageData(ssrc, event);
2316 signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
2317}
2318
2319void VideoChannel::OnStateChange(VideoCapturer* capturer, CaptureState ev) {
2320 // Map capturer events to window events. In the future we may want to simply
2321 // pass these events up directly.
2322 talk_base::WindowEvent we;
2323 if (ev == CS_STOPPED) {
2324 we = talk_base::WE_CLOSE;
2325 } else if (ev == CS_PAUSED) {
2326 we = talk_base::WE_MINIMIZE;
2327 } else if (ev == CS_RUNNING && previous_we_ == talk_base::WE_MINIMIZE) {
2328 we = talk_base::WE_RESTORE;
2329 } else {
2330 return;
2331 }
2332 previous_we_ = we;
2333
2334 uint32 ssrc = 0;
2335 if (!GetLocalSsrc(capturer, &ssrc)) {
2336 return;
2337 }
2338 ScreencastEventMessageData* pdata =
2339 new ScreencastEventMessageData(ssrc, we);
2340 signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
2341}
2342
2343bool VideoChannel::GetLocalSsrc(const VideoCapturer* capturer, uint32* ssrc) {
2344 *ssrc = 0;
2345 for (ScreencastMap::iterator iter = screencast_capturers_.begin();
2346 iter != screencast_capturers_.end(); ++iter) {
2347 if (iter->second == capturer) {
2348 *ssrc = iter->first;
2349 return true;
2350 }
2351 }
2352 return false;
2353}
2354
2355void VideoChannel::OnVideoChannelError(uint32 ssrc,
2356 VideoMediaChannel::Error error) {
2357 VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData(
2358 ssrc, error);
2359 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
2360}
2361
2362void VideoChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
2363 SrtpFilter::Error error) {
2364 switch (error) {
2365 case SrtpFilter::ERROR_FAIL:
2366 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2367 VideoMediaChannel::ERROR_REC_SRTP_ERROR :
2368 VideoMediaChannel::ERROR_PLAY_SRTP_ERROR);
2369 break;
2370 case SrtpFilter::ERROR_AUTH:
2371 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2372 VideoMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
2373 VideoMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
2374 break;
2375 case SrtpFilter::ERROR_REPLAY:
2376 // Only receving channel should have this error.
2377 ASSERT(mode == SrtpFilter::UNPROTECT);
2378 // TODO(gangji): Turn on the signaling of replay error once we have
2379 // switched to the new mechanism for doing video retransmissions.
2380 // OnVideoChannelError(ssrc, VideoMediaChannel::ERROR_PLAY_SRTP_REPLAY);
2381 break;
2382 default:
2383 break;
2384 }
2385}
2386
2387
2388void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
2389 GetSupportedVideoCryptoSuites(ciphers);
2390}
2391
2392DataChannel::DataChannel(talk_base::Thread* thread,
2393 DataMediaChannel* media_channel,
2394 BaseSession* session,
2395 const std::string& content_name,
2396 bool rtcp)
2397 // MediaEngine is NULL
2398 : BaseChannel(thread, NULL, media_channel, session, content_name, rtcp),
2399 data_channel_type_(cricket::DCT_NONE) {
2400}
2401
2402DataChannel::~DataChannel() {
2403 StopMediaMonitor();
2404 // this can't be done in the base class, since it calls a virtual
2405 DisableMedia_w();
2406}
2407
2408bool DataChannel::Init() {
2409 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
2410 content_name(), "data_rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
2411 if (!BaseChannel::Init(session()->CreateChannel(
2412 content_name(), "data_rtp", ICE_CANDIDATE_COMPONENT_RTP),
2413 rtcp_channel)) {
2414 return false;
2415 }
2416 media_channel()->SignalDataReceived.connect(
2417 this, &DataChannel::OnDataReceived);
2418 media_channel()->SignalMediaError.connect(
2419 this, &DataChannel::OnDataChannelError);
2420 srtp_filter()->SignalSrtpError.connect(
2421 this, &DataChannel::OnSrtpError);
2422 return true;
2423}
2424
2425bool DataChannel::SendData(const SendDataParams& params,
2426 const talk_base::Buffer& payload,
2427 SendDataResult* result) {
2428 SendDataMessageData message_data(params, &payload, result);
2429 Send(MSG_SENDDATA, &message_data);
2430 return message_data.succeeded;
2431}
2432
2433const ContentInfo* DataChannel::GetFirstContent(
2434 const SessionDescription* sdesc) {
2435 return GetFirstDataContent(sdesc);
2436}
2437
2438
2439static bool IsRtpPacket(const talk_base::Buffer* packet) {
2440 int version;
2441 if (!GetRtpVersion(packet->data(), packet->length(), &version)) {
2442 return false;
2443 }
2444
2445 return version == 2;
2446}
2447
2448bool DataChannel::WantsPacket(bool rtcp, talk_base::Buffer* packet) {
2449 if (data_channel_type_ == DCT_SCTP) {
2450 // TODO(pthatcher): Do this in a more robust way by checking for
2451 // SCTP or DTLS.
2452 return !IsRtpPacket(packet);
2453 } else if (data_channel_type_ == DCT_RTP) {
2454 return BaseChannel::WantsPacket(rtcp, packet);
2455 }
2456 return false;
2457}
2458
2459// Sets the maximum bandwidth. Anything over this will be dropped.
2460bool DataChannel::SetMaxSendBandwidth_w(int max_bps) {
2461 LOG(LS_INFO) << "DataChannel: Setting max bandwidth to " << max_bps;
2462 return media_channel()->SetSendBandwidth(false, max_bps);
2463}
2464
2465bool DataChannel::SetDataChannelType(DataChannelType new_data_channel_type) {
2466 // It hasn't been set before, so set it now.
2467 if (data_channel_type_ == DCT_NONE) {
2468 data_channel_type_ = new_data_channel_type;
2469 return true;
2470 }
2471
2472 // It's been set before, but doesn't match. That's bad.
2473 if (data_channel_type_ != new_data_channel_type) {
2474 LOG(LS_WARNING) << "Data channel type mismatch."
2475 << " Expected " << data_channel_type_
2476 << " Got " << new_data_channel_type;
2477 return false;
2478 }
2479
2480 // It's hasn't changed. Nothing to do.
2481 return true;
2482}
2483
2484bool DataChannel::SetDataChannelTypeFromContent(
2485 const DataContentDescription* content) {
2486 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
2487 (content->protocol() == kMediaProtocolDtlsSctp));
2488 DataChannelType data_channel_type = is_sctp ? DCT_SCTP : DCT_RTP;
2489 return SetDataChannelType(data_channel_type);
2490}
2491
2492bool DataChannel::SetLocalContent_w(const MediaContentDescription* content,
2493 ContentAction action) {
2494 ASSERT(worker_thread() == talk_base::Thread::Current());
2495 LOG(LS_INFO) << "Setting local data description";
2496
2497 const DataContentDescription* data =
2498 static_cast<const DataContentDescription*>(content);
2499 ASSERT(data != NULL);
2500 if (!data) return false;
2501
2502 bool ret = false;
2503 if (!SetDataChannelTypeFromContent(data)) {
2504 return false;
2505 }
2506
2507 if (data_channel_type_ == DCT_SCTP) {
2508 // SCTP data channels don't need the rest of the stuff.
2509 ret = UpdateLocalStreams_w(data->streams(), action);
2510 if (ret) {
2511 set_local_content_direction(content->direction());
2512 }
2513 } else {
2514 ret = SetBaseLocalContent_w(content, action);
2515
2516 if (action != CA_UPDATE || data->has_codecs()) {
2517 ret &= media_channel()->SetRecvCodecs(data->codecs());
2518 }
2519 }
2520
2521 // If everything worked, see if we can start receiving.
2522 if (ret) {
2523 ChangeState();
2524 } else {
2525 LOG(LS_WARNING) << "Failed to set local data description";
2526 }
2527 return ret;
2528}
2529
2530bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content,
2531 ContentAction action) {
2532 ASSERT(worker_thread() == talk_base::Thread::Current());
2533
2534 const DataContentDescription* data =
2535 static_cast<const DataContentDescription*>(content);
2536 ASSERT(data != NULL);
2537 if (!data) return false;
2538
2539 bool ret = true;
2540 if (!SetDataChannelTypeFromContent(data)) {
2541 return false;
2542 }
2543
2544 if (data_channel_type_ == DCT_SCTP) {
2545 LOG(LS_INFO) << "Setting SCTP remote data description";
2546 // SCTP data channels don't need the rest of the stuff.
2547 ret = UpdateRemoteStreams_w(content->streams(), action);
2548 if (ret) {
2549 set_remote_content_direction(content->direction());
2550 }
2551 } else {
2552 // If the remote data doesn't have codecs and isn't an update, it
2553 // must be empty, so ignore it.
2554 if (action != CA_UPDATE && !data->has_codecs()) {
2555 return true;
2556 }
2557 LOG(LS_INFO) << "Setting remote data description";
2558
2559 // Set remote video codecs (what the other side wants to receive).
2560 if (action != CA_UPDATE || data->has_codecs()) {
2561 ret &= media_channel()->SetSendCodecs(data->codecs());
2562 }
2563
2564 if (ret) {
2565 ret &= SetBaseRemoteContent_w(content, action);
2566 }
2567
2568 if (action != CA_UPDATE) {
2569 int bandwidth_bps = data->bandwidth();
2570 bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth);
2571 ret &= media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps);
2572 }
2573 }
2574
2575 // If everything worked, see if we can start sending.
2576 if (ret) {
2577 ChangeState();
2578 } else {
2579 LOG(LS_WARNING) << "Failed to set remote data description";
2580 }
2581 return ret;
2582}
2583
2584void DataChannel::ChangeState() {
2585 // Render incoming data if we're the active call, and we have the local
2586 // content. We receive data on the default channel and multiplexed streams.
2587 bool recv = IsReadyToReceive();
2588 if (!media_channel()->SetReceive(recv)) {
2589 LOG(LS_ERROR) << "Failed to SetReceive on data channel";
2590 }
2591
2592 // Send outgoing data if we're the active call, we have the remote content,
2593 // and we have had some form of connectivity.
2594 bool send = IsReadyToSend();
2595 if (!media_channel()->SetSend(send)) {
2596 LOG(LS_ERROR) << "Failed to SetSend on data channel";
2597 }
2598
2599 // Post to trigger SignalReadyToSendData.
2600 signaling_thread()->Post(this, MSG_READYTOSENDDATA,
2601 new BoolMessageData(send));
2602
2603 LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
2604}
2605
2606void DataChannel::OnMessage(talk_base::Message *pmsg) {
2607 switch (pmsg->message_id) {
2608 case MSG_READYTOSENDDATA: {
2609 BoolMessageData* data = static_cast<BoolMessageData*>(pmsg->pdata);
2610 SignalReadyToSendData(data->data());
2611 delete data;
2612 break;
2613 }
2614 case MSG_SENDDATA: {
2615 SendDataMessageData* msg =
2616 static_cast<SendDataMessageData*>(pmsg->pdata);
2617 msg->succeeded = media_channel()->SendData(
2618 msg->params, *(msg->payload), msg->result);
2619 break;
2620 }
2621 case MSG_DATARECEIVED: {
2622 DataReceivedMessageData* data =
2623 static_cast<DataReceivedMessageData*>(pmsg->pdata);
2624 SignalDataReceived(this, data->params, data->payload);
2625 delete data;
2626 break;
2627 }
2628 case MSG_CHANNEL_ERROR: {
2629 const DataChannelErrorMessageData* data =
2630 static_cast<DataChannelErrorMessageData*>(pmsg->pdata);
2631 SignalMediaError(this, data->ssrc, data->error);
2632 delete data;
2633 break;
2634 }
2635 default:
2636 BaseChannel::OnMessage(pmsg);
2637 break;
2638 }
2639}
2640
2641void DataChannel::OnConnectionMonitorUpdate(
2642 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
2643 SignalConnectionMonitor(this, infos);
2644}
2645
2646void DataChannel::StartMediaMonitor(int cms) {
2647 media_monitor_.reset(new DataMediaMonitor(media_channel(), worker_thread(),
2648 talk_base::Thread::Current()));
2649 media_monitor_->SignalUpdate.connect(
2650 this, &DataChannel::OnMediaMonitorUpdate);
2651 media_monitor_->Start(cms);
2652}
2653
2654void DataChannel::StopMediaMonitor() {
2655 if (media_monitor_) {
2656 media_monitor_->Stop();
2657 media_monitor_->SignalUpdate.disconnect(this);
2658 media_monitor_.reset();
2659 }
2660}
2661
2662void DataChannel::OnMediaMonitorUpdate(
2663 DataMediaChannel* media_channel, const DataMediaInfo& info) {
2664 ASSERT(media_channel == this->media_channel());
2665 SignalMediaMonitor(this, info);
2666}
2667
2668void DataChannel::OnDataReceived(
2669 const ReceiveDataParams& params, const char* data, size_t len) {
2670 DataReceivedMessageData* msg = new DataReceivedMessageData(
2671 params, data, len);
2672 signaling_thread()->Post(this, MSG_DATARECEIVED, msg);
2673}
2674
2675void DataChannel::OnDataChannelError(
2676 uint32 ssrc, DataMediaChannel::Error err) {
2677 DataChannelErrorMessageData* data = new DataChannelErrorMessageData(
2678 ssrc, err);
2679 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
2680}
2681
2682void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
2683 SrtpFilter::Error error) {
2684 switch (error) {
2685 case SrtpFilter::ERROR_FAIL:
2686 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2687 DataMediaChannel::ERROR_SEND_SRTP_ERROR :
2688 DataMediaChannel::ERROR_RECV_SRTP_ERROR);
2689 break;
2690 case SrtpFilter::ERROR_AUTH:
2691 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2692 DataMediaChannel::ERROR_SEND_SRTP_AUTH_FAILED :
2693 DataMediaChannel::ERROR_RECV_SRTP_AUTH_FAILED);
2694 break;
2695 case SrtpFilter::ERROR_REPLAY:
2696 // Only receving channel should have this error.
2697 ASSERT(mode == SrtpFilter::UNPROTECT);
2698 OnDataChannelError(ssrc, DataMediaChannel::ERROR_RECV_SRTP_REPLAY);
2699 break;
2700 default:
2701 break;
2702 }
2703}
2704
2705void DataChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
2706 GetSupportedDataCryptoSuites(ciphers);
2707}
2708
2709bool DataChannel::ShouldSetupDtlsSrtp() const {
2710 return (data_channel_type_ == DCT_RTP);
2711}
2712
2713} // namespace cricket