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