1/* 2 * libjingle 3 * Copyright 2004--2007, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "talk/session/phone/channel.h" 29 30#include "talk/base/buffer.h" 31#include "talk/base/byteorder.h" 32#include "talk/base/common.h" 33#include "talk/base/logging.h" 34#include "talk/p2p/base/transportchannel.h" 35#include "talk/session/phone/channelmanager.h" 36#include "talk/session/phone/mediasessionclient.h" 37#include "talk/session/phone/mediasink.h" 38#include "talk/session/phone/rtcpmuxfilter.h" 39 40namespace cricket { 41 42struct PacketMessageData : public talk_base::MessageData { 43 talk_base::Buffer packet; 44}; 45 46struct VoiceChannelErrorMessageData : public talk_base::MessageData { 47 VoiceChannelErrorMessageData(uint32 in_ssrc, 48 VoiceMediaChannel::Error in_error) 49 : ssrc(in_ssrc), 50 error(in_error) {} 51 uint32 ssrc; 52 VoiceMediaChannel::Error error; 53}; 54 55struct VideoChannelErrorMessageData : public talk_base::MessageData { 56 VideoChannelErrorMessageData(uint32 in_ssrc, 57 VideoMediaChannel::Error in_error) 58 : ssrc(in_ssrc), 59 error(in_error) {} 60 uint32 ssrc; 61 VideoMediaChannel::Error error; 62}; 63 64static const char* PacketType(bool rtcp) { 65 return (!rtcp) ? "RTP" : "RTCP"; 66} 67 68static bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) { 69 // Check the packet size. We could check the header too if needed. 70 return (packet && 71 packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) && 72 packet->length() <= kMaxRtpPacketLen); 73} 74 75static uint16 GetRtpSeqNum(const talk_base::Buffer* packet) { 76 return (packet->length() >= kMinRtpPacketLen) ? 77 talk_base::GetBE16(packet->data() + 2) : 0; 78} 79 80static uint32 GetRtpSsrc(const talk_base::Buffer* packet) { 81 return (packet->length() >= kMinRtpPacketLen) ? 82 talk_base::GetBE32(packet->data() + 8) : 0; 83} 84 85static int GetRtcpType(const talk_base::Buffer* packet) { 86 return (packet->length() >= kMinRtcpPacketLen) ? 87 static_cast<int>(packet->data()[1]) : 0; 88} 89 90BaseChannel::BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine, 91 MediaChannel* media_channel, BaseSession* session, 92 const std::string& content_name, 93 TransportChannel* transport_channel) 94 : worker_thread_(thread), 95 media_engine_(media_engine), 96 session_(session), 97 media_channel_(media_channel), 98 received_media_sink_(NULL), 99 sent_media_sink_(NULL), 100 content_name_(content_name), 101 transport_channel_(transport_channel), 102 rtcp_transport_channel_(NULL), 103 enabled_(false), 104 writable_(false), 105 has_codec_(false), 106 muted_(false) { 107 ASSERT(worker_thread_ == talk_base::Thread::Current()); 108 media_channel_->SetInterface(this); 109 transport_channel_->SignalWritableState.connect( 110 this, &BaseChannel::OnWritableState); 111 transport_channel_->SignalReadPacket.connect( 112 this, &BaseChannel::OnChannelRead); 113 114 LOG(LS_INFO) << "Created channel"; 115 116 session->SignalState.connect(this, &BaseChannel::OnSessionState); 117} 118 119BaseChannel::~BaseChannel() { 120 ASSERT(worker_thread_ == talk_base::Thread::Current()); 121 StopConnectionMonitor(); 122 FlushRtcpMessages(); // Send any outstanding RTCP packets. 123 Clear(); // eats any outstanding messages or packets 124 // We must destroy the media channel before the transport channel, otherwise 125 // the media channel may try to send on the dead transport channel. NULLing 126 // is not an effective strategy since the sends will come on another thread. 127 delete media_channel_; 128 set_rtcp_transport_channel(NULL); 129 if (transport_channel_ != NULL) 130 session_->DestroyChannel(content_name_, transport_channel_->name()); 131 LOG(LS_INFO) << "Destroyed channel"; 132} 133 134bool BaseChannel::Enable(bool enable) { 135 // Can be called from thread other than worker thread 136 Send(enable ? MSG_ENABLE : MSG_DISABLE); 137 return true; 138} 139 140bool BaseChannel::Mute(bool mute) { 141 // Can be called from thread other than worker thread 142 Send(mute ? MSG_MUTE : MSG_UNMUTE); 143 return true; 144} 145 146bool BaseChannel::RemoveStream(uint32 ssrc) { 147 StreamMessageData data(ssrc, 0); 148 Send(MSG_REMOVESTREAM, &data); 149 return true; 150} 151 152bool BaseChannel::SetRtcpCName(const std::string& cname) { 153 SetRtcpCNameData data(cname); 154 Send(MSG_SETRTCPCNAME, &data); 155 return data.result; 156} 157 158bool BaseChannel::SetLocalContent(const MediaContentDescription* content, 159 ContentAction action) { 160 SetContentData data(content, action); 161 Send(MSG_SETLOCALCONTENT, &data); 162 return data.result; 163} 164 165bool BaseChannel::SetRemoteContent(const MediaContentDescription* content, 166 ContentAction action) { 167 SetContentData data(content, action); 168 Send(MSG_SETREMOTECONTENT, &data); 169 return data.result; 170} 171 172bool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) { 173 SetBandwidthData data(max_bandwidth); 174 Send(MSG_SETMAXSENDBANDWIDTH, &data); 175 return data.result; 176} 177 178void BaseChannel::StartConnectionMonitor(int cms) { 179 socket_monitor_.reset(new SocketMonitor(transport_channel_, 180 worker_thread(), 181 talk_base::Thread::Current())); 182 socket_monitor_->SignalUpdate.connect( 183 this, &BaseChannel::OnConnectionMonitorUpdate); 184 socket_monitor_->Start(cms); 185} 186 187void BaseChannel::StopConnectionMonitor() { 188 if (socket_monitor_.get()) { 189 socket_monitor_->Stop(); 190 socket_monitor_.reset(); 191 } 192} 193 194void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) { 195 if (rtcp_transport_channel_ != channel) { 196 if (rtcp_transport_channel_) { 197 session_->DestroyChannel(content_name_, rtcp_transport_channel_->name()); 198 } 199 rtcp_transport_channel_ = channel; 200 if (rtcp_transport_channel_) { 201 rtcp_transport_channel_->SignalWritableState.connect( 202 this, &BaseChannel::OnWritableState); 203 rtcp_transport_channel_->SignalReadPacket.connect( 204 this, &BaseChannel::OnChannelRead); 205 } 206 } 207} 208 209bool BaseChannel::SendPacket(talk_base::Buffer* packet) { 210 return SendPacket(false, packet); 211} 212 213bool BaseChannel::SendRtcp(talk_base::Buffer* packet) { 214 return SendPacket(true, packet); 215} 216 217int BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt, 218 int value) { 219 switch (type) { 220 case ST_RTP: return transport_channel_->SetOption(opt, value); 221 case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value); 222 default: return -1; 223 } 224} 225 226void BaseChannel::OnWritableState(TransportChannel* channel) { 227 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); 228 if (transport_channel_->writable() 229 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { 230 ChannelWritable_w(); 231 } else { 232 ChannelNotWritable_w(); 233 } 234} 235 236void BaseChannel::OnChannelRead(TransportChannel* channel, 237 const char* data, size_t len) { 238 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine 239 ASSERT(worker_thread_ == talk_base::Thread::Current()); 240 241 talk_base::Buffer packet(data, len); 242 // When using RTCP multiplexing we might get RTCP packets on the RTP 243 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. 244 bool rtcp = (channel == rtcp_transport_channel_ || 245 rtcp_mux_filter_.DemuxRtcp(packet.data(), packet.length())); 246 HandlePacket(rtcp, &packet); 247} 248 249bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet) { 250 // SendPacket gets called from MediaEngine, typically on an encoder thread. 251 // If the thread is not our worker thread, we will post to our worker 252 // so that the real work happens on our worker. This avoids us having to 253 // synchronize access to all the pieces of the send path, including 254 // SRTP and the inner workings of the transport channels. 255 // The only downside is that we can't return a proper failure code if 256 // needed. Since UDP is unreliable anyway, this should be a non-issue. 257 if (talk_base::Thread::Current() != worker_thread_) { 258 // Avoid a copy by transferring the ownership of the packet data. 259 int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET; 260 PacketMessageData* data = new PacketMessageData; 261 packet->TransferTo(&data->packet); 262 worker_thread_->Post(this, message_id, data); 263 return true; 264 } 265 266 // Make sure we have a place to send this packet before doing anything. 267 // (We might get RTCP packets that we don't intend to send.) 268 // If we've negotiated RTCP mux, send RTCP over the RTP transport. 269 TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ? 270 transport_channel_ : rtcp_transport_channel_; 271 if (!channel) { 272 return false; 273 } 274 275 // Protect ourselves against crazy data. 276 if (!ValidPacket(rtcp, packet)) { 277 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " " 278 << PacketType(rtcp) << " packet: wrong size=" 279 << packet->length(); 280 return false; 281 } 282 283 // Push the packet down to the media sink. 284 // Need to do this before protecting the packet. 285 { 286 talk_base::CritScope cs(&sink_critical_section_); 287 if (sent_media_sink_) { 288 if (!rtcp) { 289 sent_media_sink_->OnRtpPacket(packet->data(), packet->length()); 290 } else { 291 sent_media_sink_->OnRtcpPacket(packet->data(), packet->length()); 292 } 293 } 294 } 295 296 // Protect if needed. 297 if (srtp_filter_.IsActive()) { 298 bool res; 299 char* data = packet->data(); 300 int len = packet->length(); 301 if (!rtcp) { 302 res = srtp_filter_.ProtectRtp(data, len, packet->capacity(), &len); 303 if (!res) { 304 LOG(LS_ERROR) << "Failed to protect " << content_name_ 305 << " RTP packet: size=" << len 306 << ", seqnum=" << GetRtpSeqNum(packet) 307 << ", SSRC=" << GetRtpSsrc(packet); 308 return false; 309 } 310 } else { 311 res = srtp_filter_.ProtectRtcp(data, len, packet->capacity(), &len); 312 if (!res) { 313 LOG(LS_ERROR) << "Failed to protect " << content_name_ 314 << " RTCP packet: size=" << len 315 << ", type=" << GetRtcpType(packet); 316 return false; 317 } 318 } 319 320 // Update the length of the packet now that we've added the auth tag. 321 packet->SetLength(len); 322 } 323 324 // Bon voyage. 325 return (channel->SendPacket(packet->data(), packet->length()) 326 == static_cast<int>(packet->length())); 327} 328 329void BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) { 330 // Protect ourselvs against crazy data. 331 if (!ValidPacket(rtcp, packet)) { 332 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " 333 << PacketType(rtcp) << " packet: wrong size=" 334 << packet->length(); 335 return; 336 } 337 338 // Unprotect the packet, if needed. 339 if (srtp_filter_.IsActive()) { 340 char* data = packet->data(); 341 int len = packet->length(); 342 bool res; 343 if (!rtcp) { 344 res = srtp_filter_.UnprotectRtp(data, len, &len); 345 if (!res) { 346 LOG(LS_ERROR) << "Failed to unprotect " << content_name_ 347 << " RTP packet: size=" << len 348 << ", seqnum=" << GetRtpSeqNum(packet) 349 << ", SSRC=" << GetRtpSsrc(packet); 350 return; 351 } 352 } else { 353 res = srtp_filter_.UnprotectRtcp(data, len, &len); 354 if (!res) { 355 LOG(LS_ERROR) << "Failed to unprotect " << content_name_ 356 << " RTCP packet: size=" << len 357 << ", type=" << GetRtcpType(packet); 358 return; 359 } 360 } 361 362 packet->SetLength(len); 363 } 364 365 // Push it down to the media channel. 366 if (!rtcp) { 367 media_channel_->OnPacketReceived(packet); 368 } else { 369 media_channel_->OnRtcpReceived(packet); 370 } 371 372 // Push it down to the media sink. 373 { 374 talk_base::CritScope cs(&sink_critical_section_); 375 if (received_media_sink_) { 376 if (!rtcp) { 377 received_media_sink_->OnRtpPacket(packet->data(), packet->length()); 378 } else { 379 received_media_sink_->OnRtcpPacket(packet->data(), packet->length()); 380 } 381 } 382 } 383} 384 385void BaseChannel::OnSessionState(BaseSession* session, 386 BaseSession::State state) { 387 const MediaContentDescription* content = NULL; 388 switch (state) { 389 case Session::STATE_SENTINITIATE: 390 content = GetFirstContent(session->local_description()); 391 if (content && !SetLocalContent(content, CA_OFFER)) { 392 LOG(LS_ERROR) << "Failure in SetLocalContent with CA_OFFER"; 393 session->SetError(BaseSession::ERROR_CONTENT); 394 } 395 break; 396 case Session::STATE_SENTACCEPT: 397 content = GetFirstContent(session->local_description()); 398 if (content && !SetLocalContent(content, CA_ANSWER)) { 399 LOG(LS_ERROR) << "Failure in SetLocalContent with CA_ANSWER"; 400 session->SetError(BaseSession::ERROR_CONTENT); 401 } 402 break; 403 case Session::STATE_RECEIVEDINITIATE: 404 content = GetFirstContent(session->remote_description()); 405 if (content && !SetRemoteContent(content, CA_OFFER)) { 406 LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_OFFER"; 407 session->SetError(BaseSession::ERROR_CONTENT); 408 } 409 break; 410 case Session::STATE_RECEIVEDACCEPT: 411 content = GetFirstContent(session->remote_description()); 412 if (content && !SetRemoteContent(content, CA_ANSWER)) { 413 LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_ANSWER"; 414 session->SetError(BaseSession::ERROR_CONTENT); 415 } 416 break; 417 default: 418 break; 419 } 420} 421 422void BaseChannel::EnableMedia_w() { 423 ASSERT(worker_thread_ == talk_base::Thread::Current()); 424 if (enabled_) 425 return; 426 427 LOG(LS_INFO) << "Channel enabled"; 428 enabled_ = true; 429 ChangeState(); 430} 431 432void BaseChannel::DisableMedia_w() { 433 ASSERT(worker_thread_ == talk_base::Thread::Current()); 434 if (!enabled_) 435 return; 436 437 LOG(LS_INFO) << "Channel disabled"; 438 enabled_ = false; 439 ChangeState(); 440} 441 442void BaseChannel::MuteMedia_w() { 443 ASSERT(worker_thread_ == talk_base::Thread::Current()); 444 if (muted_) 445 return; 446 447 if (media_channel()->Mute(true)) { 448 LOG(LS_INFO) << "Channel muted"; 449 muted_ = true; 450 } 451} 452 453void BaseChannel::UnmuteMedia_w() { 454 ASSERT(worker_thread_ == talk_base::Thread::Current()); 455 if (!muted_) 456 return; 457 458 if (media_channel()->Mute(false)) { 459 LOG(LS_INFO) << "Channel unmuted"; 460 muted_ = false; 461 } 462} 463 464void BaseChannel::ChannelWritable_w() { 465 ASSERT(worker_thread_ == talk_base::Thread::Current()); 466 if (writable_) 467 return; 468 LOG(LS_INFO) << "Channel socket writable (" 469 << transport_channel_->name().c_str() << ")"; 470 writable_ = true; 471 ChangeState(); 472} 473 474void BaseChannel::ChannelNotWritable_w() { 475 ASSERT(worker_thread_ == talk_base::Thread::Current()); 476 if (!writable_) 477 return; 478 479 LOG(LS_INFO) << "Channel socket not writable (" 480 << transport_channel_->name().c_str() << ")"; 481 writable_ = false; 482 ChangeState(); 483} 484 485// Sets the maximum video bandwidth for automatic bandwidth adjustment. 486bool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) { 487 return media_channel()->SetSendBandwidth(true, max_bandwidth); 488} 489 490bool BaseChannel::SetRtcpCName_w(const std::string& cname) { 491 return media_channel()->SetRtcpCName(cname); 492} 493 494bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, 495 ContentAction action, ContentSource src) { 496 bool ret; 497 if (action == CA_OFFER) { 498 ret = srtp_filter_.SetOffer(cryptos, src); 499 } else if (action == CA_ANSWER) { 500 ret = srtp_filter_.SetAnswer(cryptos, src); 501 } else { 502 // CA_UPDATE, no crypto params. 503 ret = true; 504 } 505 return ret; 506} 507 508bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, 509 ContentSource src) { 510 bool ret; 511 if (action == CA_OFFER) { 512 ret = rtcp_mux_filter_.SetOffer(enable, src); 513 } else if (action == CA_ANSWER) { 514 ret = rtcp_mux_filter_.SetAnswer(enable, src); 515 if (ret && rtcp_mux_filter_.IsActive()) { 516 // We activated RTCP mux, close down the RTCP transport. 517 set_rtcp_transport_channel(NULL); 518 // If the RTP transport is already writable, then so are we. 519 if (transport_channel_->writable()) { 520 ChannelWritable_w(); 521 } 522 } 523 } else { 524 // CA_UPDATE, no RTCP mux info. 525 ret = true; 526 } 527 return ret; 528} 529 530void BaseChannel::OnMessage(talk_base::Message *pmsg) { 531 switch (pmsg->message_id) { 532 case MSG_ENABLE: 533 EnableMedia_w(); 534 break; 535 case MSG_DISABLE: 536 DisableMedia_w(); 537 break; 538 539 case MSG_MUTE: 540 MuteMedia_w(); 541 break; 542 case MSG_UNMUTE: 543 UnmuteMedia_w(); 544 break; 545 546 case MSG_SETRTCPCNAME: { 547 SetRtcpCNameData* data = static_cast<SetRtcpCNameData*>(pmsg->pdata); 548 data->result = SetRtcpCName_w(data->cname); 549 break; 550 } 551 552 case MSG_SETLOCALCONTENT: { 553 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata); 554 data->result = SetLocalContent_w(data->content, data->action); 555 break; 556 } 557 case MSG_SETREMOTECONTENT: { 558 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata); 559 data->result = SetRemoteContent_w(data->content, data->action); 560 break; 561 } 562 563 case MSG_REMOVESTREAM: { 564 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 565 RemoveStream_w(data->ssrc1); 566 break; 567 } 568 569 case MSG_SETMAXSENDBANDWIDTH: { 570 SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata); 571 data->result = SetMaxSendBandwidth_w(data->value); 572 break; 573 } 574 575 case MSG_RTPPACKET: 576 case MSG_RTCPPACKET: { 577 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata); 578 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet); 579 delete data; // because it is Posted 580 break; 581 } 582 } 583} 584 585void BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) { 586 worker_thread_->Send(this, id, pdata); 587} 588 589void BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) { 590 worker_thread_->Post(this, id, pdata); 591} 592 593void BaseChannel::PostDelayed(int cmsDelay, uint32 id, 594 talk_base::MessageData *pdata) { 595 worker_thread_->PostDelayed(cmsDelay, this, id, pdata); 596} 597 598void BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) { 599 worker_thread_->Clear(this, id, removed); 600} 601 602void BaseChannel::FlushRtcpMessages() { 603 // Flush all remaining RTCP messages. This should only be called in 604 // destructor. 605 ASSERT(talk_base::Thread::Current() == worker_thread_); 606 talk_base::MessageList rtcp_messages; 607 Clear(MSG_RTCPPACKET, &rtcp_messages); 608 for (talk_base::MessageList::iterator it = rtcp_messages.begin(); 609 it != rtcp_messages.end(); ++it) { 610 Send(MSG_RTCPPACKET, it->pdata); 611 } 612} 613 614VoiceChannel::VoiceChannel(talk_base::Thread* thread, 615 MediaEngine* media_engine, 616 VoiceMediaChannel* media_channel, 617 BaseSession* session, 618 const std::string& content_name, 619 bool rtcp) 620 : BaseChannel(thread, media_engine, media_channel, session, content_name, 621 session->CreateChannel(content_name, "rtp")), 622 received_media_(false) { 623 if (rtcp) { 624 set_rtcp_transport_channel(session->CreateChannel(content_name, "rtcp")); 625 } 626 // Can't go in BaseChannel because certain session states will 627 // trigger pure virtual functions, such as GetFirstContent(). 628 OnSessionState(session, session->state()); 629 630 media_channel->SignalMediaError.connect( 631 this, &VoiceChannel::OnVoiceChannelError); 632} 633 634VoiceChannel::~VoiceChannel() { 635 StopAudioMonitor(); 636 StopMediaMonitor(); 637 // this can't be done in the base class, since it calls a virtual 638 DisableMedia_w(); 639} 640 641bool VoiceChannel::AddStream(uint32 ssrc) { 642 StreamMessageData data(ssrc, 0); 643 Send(MSG_ADDSTREAM, &data); 644 return true; 645} 646 647bool VoiceChannel::SetRingbackTone(const void* buf, int len) { 648 SetRingbackToneMessageData data(buf, len); 649 Send(MSG_SETRINGBACKTONE, &data); 650 return true; 651} 652 653// TODO: Handle early media the right way. We should get an explicit 654// ringing message telling us to start playing local ringback, which we cancel 655// if any early media actually arrives. For now, we do the opposite, which is 656// to wait 1 second for early media, and start playing local ringback if none 657// arrives. 658void VoiceChannel::SetEarlyMedia(bool enable) { 659 if (enable) { 660 // Start the early media timeout 661 PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT); 662 } else { 663 // Stop the timeout if currently going. 664 Clear(MSG_EARLYMEDIATIMEOUT); 665 } 666} 667 668bool VoiceChannel::PlayRingbackTone(bool play, bool loop) { 669 PlayRingbackToneMessageData data(play, loop); 670 Send(MSG_PLAYRINGBACKTONE, &data); 671 return data.result; 672} 673 674bool VoiceChannel::PressDTMF(int digit, bool playout) { 675 DtmfMessageData data(digit, playout); 676 Send(MSG_PRESSDTMF, &data); 677 return data.result; 678} 679 680void VoiceChannel::StartMediaMonitor(int cms) { 681 media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(), 682 talk_base::Thread::Current())); 683 media_monitor_->SignalUpdate.connect( 684 this, &VoiceChannel::OnMediaMonitorUpdate); 685 media_monitor_->Start(cms); 686} 687 688void VoiceChannel::StopMediaMonitor() { 689 if (media_monitor_.get()) { 690 media_monitor_->Stop(); 691 media_monitor_->SignalUpdate.disconnect(this); 692 media_monitor_.reset(); 693 } 694} 695 696void VoiceChannel::StartAudioMonitor(int cms) { 697 audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current())); 698 audio_monitor_ 699 ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate); 700 audio_monitor_->Start(cms); 701} 702 703void VoiceChannel::StopAudioMonitor() { 704 if (audio_monitor_.get()) { 705 audio_monitor_->Stop(); 706 audio_monitor_.reset(); 707 } 708} 709 710int VoiceChannel::GetInputLevel_w() { 711 return media_engine()->GetInputLevel(); 712} 713 714int VoiceChannel::GetOutputLevel_w() { 715 return media_channel()->GetOutputLevel(); 716} 717 718void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) { 719 media_channel()->GetActiveStreams(actives); 720} 721 722void VoiceChannel::OnChannelRead(TransportChannel* channel, 723 const char* data, size_t len) { 724 BaseChannel::OnChannelRead(channel, data, len); 725 726 // Set a flag when we've received an RTP packet. If we're waiting for early 727 // media, this will disable the timeout. 728 // If we were playing out our local ringback, make sure it is stopped to 729 // prevent it from interfering with the incoming media. 730 if (!received_media_) { 731 if (!PlayRingbackTone_w(false, false)) { 732 LOG(LS_ERROR) << "Failed to stop ringback tone."; 733 SendLastMediaError(); 734 } 735 } 736} 737 738void VoiceChannel::ChangeState() { 739 // render incoming data if we are the active call 740 // we receive data on the default channel and multiplexed streams 741 bool recv = enabled(); 742 if (!media_channel()->SetPlayout(recv)) { 743 SendLastMediaError(); 744 } 745 746 // send outgoing data if we are the active call, have the 747 // remote party's codec, and have a writable transport 748 // we only send data on the default channel 749 bool send = enabled() && has_codec() && writable(); 750 SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING; 751 if (!media_channel()->SetSend(send_flag)) { 752 LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel"; 753 SendLastMediaError(); 754 } 755 756 LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send; 757} 758 759const MediaContentDescription* VoiceChannel::GetFirstContent( 760 const SessionDescription* sdesc) { 761 const ContentInfo* cinfo = GetFirstAudioContent(sdesc); 762 if (cinfo == NULL) 763 return NULL; 764 765 return static_cast<const MediaContentDescription*>(cinfo->description); 766} 767 768bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, 769 ContentAction action) { 770 ASSERT(worker_thread() == talk_base::Thread::Current()); 771 LOG(LS_INFO) << "Setting local voice description"; 772 773 const AudioContentDescription* audio = 774 static_cast<const AudioContentDescription*>(content); 775 ASSERT(audio != NULL); 776 777 bool ret; 778 // set SRTP 779 ret = SetSrtp_w(audio->cryptos(), action, CS_LOCAL); 780 // set RTCP mux 781 if (ret) { 782 ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_LOCAL); 783 } 784 // set payload type and config for voice codecs 785 if (ret) { 786 ret = media_channel()->SetRecvCodecs(audio->codecs()); 787 } 788 return ret; 789} 790 791bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, 792 ContentAction action) { 793 ASSERT(worker_thread() == talk_base::Thread::Current()); 794 LOG(LS_INFO) << "Setting remote voice description"; 795 796 const AudioContentDescription* audio = 797 static_cast<const AudioContentDescription*>(content); 798 ASSERT(audio != NULL); 799 800 bool ret; 801 // set the sending SSRC, if the remote side gave us one 802 if (audio->ssrc_set()) { 803 media_channel()->SetSendSsrc(audio->ssrc()); 804 } 805 // set SRTP 806 ret = SetSrtp_w(audio->cryptos(), action, CS_REMOTE); 807 // set RTCP mux 808 if (ret) { 809 ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_REMOTE); 810 } 811 // set codecs and payload types 812 if (ret) { 813 ret = media_channel()->SetSendCodecs(audio->codecs()); 814 } 815 816 int audio_options = 0; 817 if (audio->conference_mode()) { 818 audio_options |= OPT_CONFERENCE; 819 } 820 if (!media_channel()->SetOptions(audio_options)) { 821 // Log an error on failure, but don't abort the call. 822 LOG(LS_ERROR) << "Failed to set voice channel options"; 823 } 824 825 // update state 826 if (ret) { 827 set_has_codec(true); 828 ChangeState(); 829 } 830 return ret; 831} 832 833void VoiceChannel::AddStream_w(uint32 ssrc) { 834 ASSERT(worker_thread() == talk_base::Thread::Current()); 835 media_channel()->AddStream(ssrc); 836} 837 838void VoiceChannel::RemoveStream_w(uint32 ssrc) { 839 media_channel()->RemoveStream(ssrc); 840} 841 842void VoiceChannel::SetRingbackTone_w(const void* buf, int len) { 843 ASSERT(worker_thread() == talk_base::Thread::Current()); 844 media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); 845} 846 847bool VoiceChannel::PlayRingbackTone_w(bool play, bool loop) { 848 ASSERT(worker_thread() == talk_base::Thread::Current()); 849 if (play) { 850 LOG(LS_INFO) << "Playing ringback tone, loop=" << loop; 851 } else { 852 LOG(LS_INFO) << "Stopping ringback tone"; 853 } 854 return media_channel()->PlayRingbackTone(play, loop); 855} 856 857void VoiceChannel::HandleEarlyMediaTimeout() { 858 // This occurs on the main thread, not the worker thread. 859 if (!received_media_) { 860 LOG(LS_INFO) << "No early media received before timeout"; 861 SignalEarlyMediaTimeout(this); 862 } 863} 864 865bool VoiceChannel::PressDTMF_w(int digit, bool playout) { 866 if (!enabled() || !writable()) { 867 return false; 868 } 869 870 return media_channel()->PressDTMF(digit, playout); 871} 872 873void VoiceChannel::OnMessage(talk_base::Message *pmsg) { 874 switch (pmsg->message_id) { 875 case MSG_ADDSTREAM: { 876 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 877 AddStream_w(data->ssrc1); 878 break; 879 } 880 case MSG_SETRINGBACKTONE: { 881 SetRingbackToneMessageData* data = 882 static_cast<SetRingbackToneMessageData*>(pmsg->pdata); 883 SetRingbackTone_w(data->buf, data->len); 884 break; 885 } 886 case MSG_PLAYRINGBACKTONE: { 887 PlayRingbackToneMessageData* data = 888 static_cast<PlayRingbackToneMessageData*>(pmsg->pdata); 889 data->result = PlayRingbackTone_w(data->play, data->loop); 890 break; 891 } 892 case MSG_EARLYMEDIATIMEOUT: 893 HandleEarlyMediaTimeout(); 894 break; 895 case MSG_PRESSDTMF: { 896 DtmfMessageData* data = static_cast<DtmfMessageData*>(pmsg->pdata); 897 data->result = PressDTMF_w(data->digit, data->playout); 898 break; 899 } 900 case MSG_CHANNEL_ERROR: { 901 VoiceChannelErrorMessageData* data = 902 static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata); 903 SignalMediaError(this, data->ssrc, data->error); 904 delete data; 905 break; 906 } 907 908 default: 909 BaseChannel::OnMessage(pmsg); 910 break; 911 } 912} 913 914void VoiceChannel::OnConnectionMonitorUpdate( 915 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) { 916 SignalConnectionMonitor(this, infos); 917} 918 919void VoiceChannel::OnMediaMonitorUpdate( 920 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) { 921 ASSERT(media_channel == this->media_channel()); 922 SignalMediaMonitor(this, info); 923} 924 925void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor, 926 const AudioInfo& info) { 927 SignalAudioMonitor(this, info); 928} 929 930void VoiceChannel::OnVoiceChannelError( 931 uint32 ssrc, VoiceMediaChannel::Error error) { 932 VoiceChannelErrorMessageData *data = new VoiceChannelErrorMessageData( 933 ssrc, error); 934 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data); 935} 936 937VideoChannel::VideoChannel(talk_base::Thread* thread, 938 MediaEngine* media_engine, 939 VideoMediaChannel* media_channel, 940 BaseSession* session, 941 const std::string& content_name, 942 bool rtcp, 943 VoiceChannel* voice_channel) 944 : BaseChannel(thread, media_engine, media_channel, session, content_name, 945 session->CreateChannel(content_name, "video_rtp")), 946 voice_channel_(voice_channel), renderer_(NULL) { 947 if (rtcp) { 948 set_rtcp_transport_channel( 949 session->CreateChannel(content_name, "video_rtcp")); 950 } 951 // Can't go in BaseChannel because certain session states will 952 // trigger pure virtual functions, such as GetFirstContent() 953 OnSessionState(session, session->state()); 954 955 media_channel->SignalMediaError.connect( 956 this, &VideoChannel::OnVideoChannelError); 957} 958 959void VoiceChannel::SendLastMediaError() { 960 uint32 ssrc; 961 VoiceMediaChannel::Error error; 962 media_channel()->GetLastMediaError(&ssrc, &error); 963 SignalMediaError(this, ssrc, error); 964} 965 966VideoChannel::~VideoChannel() { 967 StopMediaMonitor(); 968 // this can't be done in the base class, since it calls a virtual 969 DisableMedia_w(); 970} 971 972bool VideoChannel::AddStream(uint32 ssrc, uint32 voice_ssrc) { 973 StreamMessageData data(ssrc, voice_ssrc); 974 Send(MSG_ADDSTREAM, &data); 975 return true; 976} 977 978bool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 979 RenderMessageData data(ssrc, renderer); 980 Send(MSG_SETRENDERER, &data); 981 return true; 982} 983 984 985 986bool VideoChannel::SendIntraFrame() { 987 Send(MSG_SENDINTRAFRAME); 988 return true; 989} 990bool VideoChannel::RequestIntraFrame() { 991 Send(MSG_REQUESTINTRAFRAME); 992 return true; 993} 994 995void VideoChannel::ChangeState() { 996 // render incoming data if we are the active call 997 // we receive data on the default channel and multiplexed streams 998 bool recv = enabled(); 999 if (!media_channel()->SetRender(recv)) { 1000 LOG(LS_ERROR) << "Failed to SetRender on video channel"; 1001 // TODO: Report error back to server. 1002 } 1003 1004 // send outgoing data if we are the active call, have the 1005 // remote party's codec, and have a writable transport 1006 // we only send data on the default channel 1007 bool send = enabled() && has_codec() && writable(); 1008 if (!media_channel()->SetSend(send)) { 1009 LOG(LS_ERROR) << "Failed to SetSend on video channel"; 1010 // TODO: Report error back to server. 1011 } 1012 1013 LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send; 1014} 1015 1016void VideoChannel::StartMediaMonitor(int cms) { 1017 media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(), 1018 talk_base::Thread::Current())); 1019 media_monitor_->SignalUpdate.connect( 1020 this, &VideoChannel::OnMediaMonitorUpdate); 1021 media_monitor_->Start(cms); 1022} 1023 1024void VideoChannel::StopMediaMonitor() { 1025 if (media_monitor_.get()) { 1026 media_monitor_->Stop(); 1027 media_monitor_.reset(); 1028 } 1029} 1030 1031const MediaContentDescription* VideoChannel::GetFirstContent( 1032 const SessionDescription* sdesc) { 1033 const ContentInfo* cinfo = GetFirstVideoContent(sdesc); 1034 if (cinfo == NULL) 1035 return NULL; 1036 1037 return static_cast<const MediaContentDescription*>(cinfo->description); 1038} 1039 1040bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, 1041 ContentAction action) { 1042 ASSERT(worker_thread() == talk_base::Thread::Current()); 1043 LOG(LS_INFO) << "Setting local video description"; 1044 1045 const VideoContentDescription* video = 1046 static_cast<const VideoContentDescription*>(content); 1047 ASSERT(video != NULL); 1048 1049 bool ret; 1050 // set SRTP 1051 ret = SetSrtp_w(video->cryptos(), action, CS_LOCAL); 1052 // set RTCP mux 1053 if (ret) { 1054 ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_LOCAL); 1055 } 1056 // set payload types and config for receiving video 1057 if (ret) { 1058 ret = media_channel()->SetRecvCodecs(video->codecs()); 1059 } 1060 return ret; 1061} 1062 1063bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, 1064 ContentAction action) { 1065 ASSERT(worker_thread() == talk_base::Thread::Current()); 1066 LOG(LS_INFO) << "Setting remote video description"; 1067 1068 const VideoContentDescription* video = 1069 static_cast<const VideoContentDescription*>(content); 1070 ASSERT(video != NULL); 1071 1072 bool ret; 1073 // set the sending SSRC, if the remote side gave us one 1074 // TODO: remove this, since it's not needed. 1075 if (video->ssrc_set()) { 1076 media_channel()->SetSendSsrc(video->ssrc()); 1077 } 1078 // set SRTP 1079 ret = SetSrtp_w(video->cryptos(), action, CS_REMOTE); 1080 // set RTCP mux 1081 if (ret) { 1082 ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_REMOTE); 1083 } 1084 // Set video bandwidth parameters. 1085 if (ret) { 1086 int bandwidth_bps = video->bandwidth(); 1087 bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth); 1088 ret = media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps); 1089 } 1090 if (ret) { 1091 ret = media_channel()->SetSendCodecs(video->codecs()); 1092 } 1093 media_channel()->SetRtpExtensionHeaders(!video->rtp_headers_disabled()); 1094 if (ret) { 1095 set_has_codec(true); 1096 ChangeState(); 1097 } 1098 return ret; 1099} 1100 1101void VideoChannel::AddStream_w(uint32 ssrc, uint32 voice_ssrc) { 1102 media_channel()->AddStream(ssrc, voice_ssrc); 1103} 1104 1105void VideoChannel::RemoveStream_w(uint32 ssrc) { 1106 media_channel()->RemoveStream(ssrc); 1107} 1108 1109void VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) { 1110 media_channel()->SetRenderer(ssrc, renderer); 1111} 1112 1113 1114void VideoChannel::OnMessage(talk_base::Message *pmsg) { 1115 switch (pmsg->message_id) { 1116 case MSG_ADDSTREAM: { 1117 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 1118 AddStream_w(data->ssrc1, data->ssrc2); 1119 break; 1120 } 1121 case MSG_SETRENDERER: { 1122 RenderMessageData* data = static_cast<RenderMessageData*>(pmsg->pdata); 1123 SetRenderer_w(data->ssrc, data->renderer); 1124 break; 1125 } 1126 case MSG_SENDINTRAFRAME: 1127 SendIntraFrame_w(); 1128 break; 1129 case MSG_REQUESTINTRAFRAME: 1130 RequestIntraFrame_w(); 1131 break; 1132 case MSG_CHANNEL_ERROR: { 1133 const VideoChannelErrorMessageData* data = 1134 static_cast<VideoChannelErrorMessageData*>(pmsg->pdata); 1135 SignalMediaError(this, data->ssrc, data->error); 1136 delete data; 1137 break; 1138 } 1139 default: 1140 BaseChannel::OnMessage(pmsg); 1141 break; 1142 } 1143} 1144 1145void VideoChannel::OnConnectionMonitorUpdate( 1146 SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) { 1147 SignalConnectionMonitor(this, infos); 1148} 1149 1150void VideoChannel::OnMediaMonitorUpdate( 1151 VideoMediaChannel* media_channel, const VideoMediaInfo &info) { 1152 ASSERT(media_channel == this->media_channel()); 1153 SignalMediaMonitor(this, info); 1154} 1155 1156 1157void VideoChannel::OnVideoChannelError(uint32 ssrc, 1158 VideoMediaChannel::Error error) { 1159 VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData( 1160 ssrc, error); 1161 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data); 1162} 1163 1164} // namespace cricket 1165