1 /* 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 <string> 29 #include "talk/media/base/constants.h" 30 #include "talk/media/base/screencastid.h" 31 #include "talk/p2p/base/parsing.h" 32 #include "talk/session/media/call.h" 33 #include "talk/session/media/currentspeakermonitor.h" 34 #include "talk/session/media/mediasessionclient.h" 35 #include "webrtc/base/helpers.h" 36 #include "webrtc/base/logging.h" 37 #include "webrtc/base/thread.h" 38 #include "webrtc/base/window.h" 39 40 namespace cricket { 41 42 const uint32 MSG_CHECKAUTODESTROY = 1; 43 const uint32 MSG_TERMINATECALL = 2; 44 const uint32 MSG_PLAYDTMF = 3; 45 46 namespace { 47 const int kDTMFDelay = 300; // msec 48 const size_t kMaxDTMFDigits = 30; 49 const int kSendToVoicemailTimeout = 1000*20; 50 const int kNoVoicemailTimeout = 1000*180; 51 const int kMediaMonitorInterval = 1000*15; 52 // In order to be the same as the server-side switching, this must be 100. 53 const int kAudioMonitorPollPeriodMillis = 100; 54 55 // V is a pointer type. 56 template<class K, class V> 57 V FindOrNull(const std::map<K, V>& map, 58 const K& key) { 59 typename std::map<K, V>::const_iterator it = map.find(key); 60 return (it != map.end()) ? it->second : NULL; 61 } 62 63 64 bool ContentContainsCrypto(const cricket::ContentInfo* content) { 65 if (content != NULL) { 66 const cricket::MediaContentDescription* desc = 67 static_cast<const cricket::MediaContentDescription*>( 68 content->description); 69 if (!desc || desc->cryptos().empty()) { 70 return false; 71 } 72 } 73 return true; 74 } 75 76 } 77 78 AudioSourceProxy::AudioSourceProxy(Call* call) 79 : call_(call) { 80 call_->SignalAudioMonitor.connect(this, &AudioSourceProxy::OnAudioMonitor); 81 call_->SignalMediaStreamsUpdate.connect( 82 this, &AudioSourceProxy::OnMediaStreamsUpdate); 83 } 84 85 void AudioSourceProxy::OnAudioMonitor(Call* call, const AudioInfo& info) { 86 SignalAudioMonitor(this, info); 87 } 88 89 void AudioSourceProxy::OnMediaStreamsUpdate(Call* call, Session* session, 90 const MediaStreams& added, const MediaStreams& removed) { 91 SignalMediaStreamsUpdate(this, session, added, removed); 92 } 93 94 Call::Call(MediaSessionClient* session_client) 95 : id_(rtc::CreateRandomId()), 96 session_client_(session_client), 97 has_video_(false), 98 has_data_(false), 99 muted_(false), 100 video_muted_(false), 101 send_to_voicemail_(true), 102 playing_dtmf_(false) { 103 audio_source_proxy_.reset(new AudioSourceProxy(this)); 104 } 105 106 Call::~Call() { 107 while (media_session_map_.begin() != media_session_map_.end()) { 108 Session* session = media_session_map_.begin()->second.session; 109 RemoveSession(session); 110 session_client_->session_manager()->DestroySession(session); 111 } 112 rtc::Thread::Current()->Clear(this); 113 } 114 115 Session* Call::InitiateSession(const buzz::Jid& to, 116 const buzz::Jid& initiator, 117 const CallOptions& options) { 118 std::string id; 119 std::string initiator_name = initiator.Str(); 120 return InternalInitiateSession(id, to, initiator_name, options); 121 } 122 123 Session *Call::InitiateSession(const std::string& id, 124 const buzz::Jid& to, 125 const CallOptions& options) { 126 std::string initiator_name; 127 return InternalInitiateSession(id, to, initiator_name, options); 128 } 129 130 void Call::IncomingSession(Session* session, const SessionDescription* offer) { 131 AddSession(session, offer); 132 133 // Make sure the session knows about the incoming ssrcs. This needs to be done 134 // prior to the SignalSessionState call, because that may trigger handling of 135 // these new SSRCs, so they need to be registered before then. 136 UpdateRemoteMediaStreams(session, offer->contents(), false); 137 138 // Missed the first state, the initiate, which is needed by 139 // call_client. 140 SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE); 141 } 142 143 void Call::AcceptSession(Session* session, 144 const cricket::CallOptions& options) { 145 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 146 if (it != media_session_map_.end()) { 147 const SessionDescription* answer = session_client_->CreateAnswer( 148 session->remote_description(), options); 149 it->second.session->Accept(answer); 150 } 151 } 152 153 void Call::RejectSession(Session* session) { 154 // Assume polite decline. 155 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 156 if (it != media_session_map_.end()) 157 it->second.session->Reject(STR_TERMINATE_DECLINE); 158 } 159 160 void Call::TerminateSession(Session* session) { 161 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 162 if (it != media_session_map_.end()) { 163 // Assume polite terminations. 164 it->second.session->Terminate(); 165 } 166 } 167 168 void Call::Terminate() { 169 // Copy the list so that we can iterate over it in a stable way 170 std::vector<Session*> sessions = this->sessions(); 171 172 // There may be more than one session to terminate 173 std::vector<Session*>::iterator it; 174 for (it = sessions.begin(); it != sessions.end(); ++it) { 175 TerminateSession(*it); 176 } 177 } 178 179 bool Call::SendViewRequest(Session* session, 180 const ViewRequest& view_request) { 181 StaticVideoViews::const_iterator it; 182 for (it = view_request.static_video_views.begin(); 183 it != view_request.static_video_views.end(); ++it) { 184 StreamParams found_stream; 185 bool found = false; 186 MediaStreams* recv_streams = GetMediaStreams(session); 187 if (recv_streams) 188 found = recv_streams->GetVideoStream(it->selector, &found_stream); 189 if (!found) { 190 LOG(LS_WARNING) << "Trying to send view request for (" 191 << it->selector.ssrc << ", '" 192 << it->selector.groupid << "', '" 193 << it->selector.streamid << "'" 194 << ") is not in the local streams."; 195 return false; 196 } 197 } 198 199 XmlElements elems; 200 WriteError error; 201 if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) { 202 LOG(LS_ERROR) << "Couldn't write out view request: " << error.text; 203 return false; 204 } 205 206 return session->SendInfoMessage(elems, session->remote_name()); 207 } 208 209 void Call::SetVideoRenderer(Session* session, uint32 ssrc, 210 VideoRenderer* renderer) { 211 VideoChannel* video_channel = GetVideoChannel(session); 212 if (video_channel) { 213 video_channel->SetRenderer(ssrc, renderer); 214 LOG(LS_INFO) << "Set renderer of ssrc " << ssrc 215 << " to " << renderer << "."; 216 } else { 217 LOG(LS_INFO) << "Failed to set renderer of ssrc " << ssrc << "."; 218 } 219 } 220 221 void Call::OnMessage(rtc::Message* message) { 222 switch (message->message_id) { 223 case MSG_CHECKAUTODESTROY: 224 // If no more sessions for this call, delete it 225 if (media_session_map_.empty()) 226 session_client_->DestroyCall(this); 227 break; 228 case MSG_TERMINATECALL: 229 // Signal to the user that a timeout has happened and the call should 230 // be sent to voicemail. 231 if (send_to_voicemail_) { 232 SignalSetupToCallVoicemail(); 233 } 234 235 // Callee didn't answer - terminate call 236 Terminate(); 237 break; 238 case MSG_PLAYDTMF: 239 ContinuePlayDTMF(); 240 } 241 } 242 243 std::vector<Session*> Call::sessions() { 244 std::vector<Session*> sessions; 245 MediaSessionMap::iterator it; 246 for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) 247 sessions.push_back(it->second.session); 248 249 return sessions; 250 } 251 252 bool Call::AddSession(Session* session, const SessionDescription* offer) { 253 bool succeeded = true; 254 MediaSession media_session; 255 media_session.session = session; 256 media_session.voice_channel = NULL; 257 media_session.video_channel = NULL; 258 media_session.data_channel = NULL; 259 media_session.recv_streams = NULL; 260 261 const ContentInfo* audio_offer = GetFirstAudioContent(offer); 262 const ContentInfo* video_offer = GetFirstVideoContent(offer); 263 const ContentInfo* data_offer = GetFirstDataContent(offer); 264 has_video_ = (video_offer != NULL); 265 has_data_ = (data_offer != NULL); 266 267 ASSERT(audio_offer != NULL); 268 // Create voice channel and start a media monitor. 269 media_session.voice_channel = 270 session_client_->channel_manager()->CreateVoiceChannel( 271 session, audio_offer->name, has_video_); 272 // voice_channel can be NULL in case of NullVoiceEngine. 273 if (media_session.voice_channel) { 274 media_session.voice_channel->SignalMediaMonitor.connect( 275 this, &Call::OnMediaMonitor); 276 media_session.voice_channel->StartMediaMonitor(kMediaMonitorInterval); 277 } else { 278 succeeded = false; 279 } 280 281 // If desired, create video channel and start a media monitor. 282 if (has_video_ && succeeded) { 283 media_session.video_channel = 284 session_client_->channel_manager()->CreateVideoChannel( 285 session, video_offer->name, true, media_session.voice_channel); 286 // video_channel can be NULL in case of NullVideoEngine. 287 if (media_session.video_channel) { 288 media_session.video_channel->SignalMediaMonitor.connect( 289 this, &Call::OnMediaMonitor); 290 media_session.video_channel->StartMediaMonitor(kMediaMonitorInterval); 291 } else { 292 succeeded = false; 293 } 294 } 295 296 // If desired, create data channel. 297 if (has_data_ && succeeded) { 298 const DataContentDescription* data = GetFirstDataContentDescription(offer); 299 if (data == NULL) { 300 succeeded = false; 301 } else { 302 DataChannelType data_channel_type = DCT_RTP; 303 if ((data->protocol() == kMediaProtocolSctp) || 304 (data->protocol() == kMediaProtocolDtlsSctp)) { 305 data_channel_type = DCT_SCTP; 306 } 307 308 bool rtcp = false; 309 media_session.data_channel = 310 session_client_->channel_manager()->CreateDataChannel( 311 session, data_offer->name, rtcp, data_channel_type); 312 if (media_session.data_channel) { 313 media_session.data_channel->SignalDataReceived.connect( 314 this, &Call::OnDataReceived); 315 } else { 316 succeeded = false; 317 } 318 } 319 } 320 321 if (succeeded) { 322 // Add session to list, create channels for this session. 323 media_session.recv_streams = new MediaStreams; 324 media_session_map_[session->id()] = media_session; 325 session->SignalState.connect(this, &Call::OnSessionState); 326 session->SignalError.connect(this, &Call::OnSessionError); 327 session->SignalInfoMessage.connect( 328 this, &Call::OnSessionInfoMessage); 329 session->SignalRemoteDescriptionUpdate.connect( 330 this, &Call::OnRemoteDescriptionUpdate); 331 session->SignalReceivedTerminateReason 332 .connect(this, &Call::OnReceivedTerminateReason); 333 334 // If this call has the focus, enable this session's channels. 335 if (session_client_->GetFocus() == this) { 336 EnableSessionChannels(session, true); 337 } 338 339 // Signal client. 340 SignalAddSession(this, session); 341 } 342 343 return succeeded; 344 } 345 346 void Call::RemoveSession(Session* session) { 347 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 348 if (it == media_session_map_.end()) 349 return; 350 351 // Remove all the screencasts, if they haven't been already. 352 while (!it->second.started_screencasts.empty()) { 353 uint32 ssrc = it->second.started_screencasts.begin()->first; 354 if (!StopScreencastWithoutSendingUpdate(it->second.session, ssrc)) { 355 LOG(LS_ERROR) << "Unable to stop screencast with ssrc " << ssrc; 356 ASSERT(false); 357 } 358 } 359 360 // Destroy video channel 361 VideoChannel* video_channel = it->second.video_channel; 362 if (video_channel != NULL) 363 session_client_->channel_manager()->DestroyVideoChannel(video_channel); 364 365 // Destroy voice channel 366 VoiceChannel* voice_channel = it->second.voice_channel; 367 if (voice_channel != NULL) 368 session_client_->channel_manager()->DestroyVoiceChannel(voice_channel); 369 370 // Destroy data channel 371 DataChannel* data_channel = it->second.data_channel; 372 if (data_channel != NULL) 373 session_client_->channel_manager()->DestroyDataChannel(data_channel); 374 375 delete it->second.recv_streams; 376 media_session_map_.erase(it); 377 378 // Destroy speaker monitor 379 StopSpeakerMonitor(session); 380 381 // Signal client 382 SignalRemoveSession(this, session); 383 384 // The call auto destroys when the last session is removed 385 rtc::Thread::Current()->Post(this, MSG_CHECKAUTODESTROY); 386 } 387 388 VoiceChannel* Call::GetVoiceChannel(Session* session) const { 389 MediaSessionMap::const_iterator it = media_session_map_.find(session->id()); 390 return (it != media_session_map_.end()) ? it->second.voice_channel : NULL; 391 } 392 393 VideoChannel* Call::GetVideoChannel(Session* session) const { 394 MediaSessionMap::const_iterator it = media_session_map_.find(session->id()); 395 return (it != media_session_map_.end()) ? it->second.video_channel : NULL; 396 } 397 398 DataChannel* Call::GetDataChannel(Session* session) const { 399 MediaSessionMap::const_iterator it = media_session_map_.find(session->id()); 400 return (it != media_session_map_.end()) ? it->second.data_channel : NULL; 401 } 402 403 MediaStreams* Call::GetMediaStreams(Session* session) const { 404 MediaSessionMap::const_iterator it = media_session_map_.find(session->id()); 405 return (it != media_session_map_.end()) ? it->second.recv_streams : NULL; 406 } 407 408 void Call::EnableChannels(bool enable) { 409 MediaSessionMap::iterator it; 410 for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) { 411 EnableSessionChannels(it->second.session, enable); 412 } 413 } 414 415 void Call::EnableSessionChannels(Session* session, bool enable) { 416 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 417 if (it == media_session_map_.end()) 418 return; 419 420 VoiceChannel* voice_channel = it->second.voice_channel; 421 VideoChannel* video_channel = it->second.video_channel; 422 DataChannel* data_channel = it->second.data_channel; 423 if (voice_channel != NULL) 424 voice_channel->Enable(enable); 425 if (video_channel != NULL) 426 video_channel->Enable(enable); 427 if (data_channel != NULL) 428 data_channel->Enable(enable); 429 } 430 431 void Call::Mute(bool mute) { 432 muted_ = mute; 433 MediaSessionMap::iterator it; 434 for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) { 435 if (it->second.voice_channel != NULL) 436 it->second.voice_channel->MuteStream(0, mute); 437 } 438 } 439 440 void Call::MuteVideo(bool mute) { 441 video_muted_ = mute; 442 MediaSessionMap::iterator it; 443 for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) { 444 if (it->second.video_channel != NULL) 445 it->second.video_channel->MuteStream(0, mute); 446 } 447 } 448 449 bool Call::SendData(Session* session, 450 const SendDataParams& params, 451 const rtc::Buffer& payload, 452 SendDataResult* result) { 453 DataChannel* data_channel = GetDataChannel(session); 454 if (!data_channel) { 455 LOG(LS_WARNING) << "Could not send data: no data channel."; 456 return false; 457 } 458 459 return data_channel->SendData(params, payload, result); 460 } 461 462 void Call::PressDTMF(int event) { 463 // Queue up this digit 464 if (queued_dtmf_.size() < kMaxDTMFDigits) { 465 LOG(LS_INFO) << "Call::PressDTMF(" << event << ")"; 466 467 queued_dtmf_.push_back(event); 468 469 if (!playing_dtmf_) { 470 ContinuePlayDTMF(); 471 } 472 } 473 } 474 475 cricket::VideoFormat ScreencastFormatFromFps(int fps) { 476 // The capturer pretty much ignore this, but just in case we give it 477 // a resolution big enough to cover any expected desktop. In any 478 // case, it can't be 0x0, or the CaptureManager will fail to use it. 479 return cricket::VideoFormat( 480 1, 1, 481 cricket::VideoFormat::FpsToInterval(fps), cricket::FOURCC_ANY); 482 } 483 484 bool Call::StartScreencast(Session* session, 485 const std::string& streamid, uint32 ssrc, 486 const ScreencastId& screenid, int fps) { 487 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 488 if (it == media_session_map_.end()) { 489 return false; 490 } 491 492 VideoChannel *video_channel = GetVideoChannel(session); 493 if (!video_channel) { 494 LOG(LS_WARNING) << "Cannot add screencast" 495 << " because there is no video channel."; 496 return false; 497 } 498 499 VideoCapturer* capturer = session_client_->channel_manager()-> 500 CreateScreenCapturer(screenid); 501 if (!capturer) { 502 LOG(LS_WARNING) << "Could not create screencast capturer."; 503 return false; 504 } 505 506 if (!video_channel->AddScreencast(ssrc, capturer)) { 507 delete capturer; 508 LOG(LS_WARNING) << "Could not add screencast capturer."; 509 return false; 510 } 511 512 VideoFormat format = ScreencastFormatFromFps(fps); 513 if (!session_client_->channel_manager()->StartVideoCapture( 514 capturer, format)) { 515 LOG(LS_WARNING) << "Could not start video capture."; 516 video_channel->RemoveScreencast(ssrc); 517 return false; 518 } 519 520 if (!video_channel->SetCapturer(ssrc, capturer)) { 521 LOG(LS_WARNING) << "Could not start sending screencast."; 522 session_client_->channel_manager()->StopVideoCapture( 523 capturer, ScreencastFormatFromFps(fps)); 524 video_channel->RemoveScreencast(ssrc); 525 } 526 527 // TODO(pthatcher): Once the CaptureManager has a nicer interface 528 // for removing captures (such as having StartCapture return a 529 // handle), remove this StartedCapture stuff. 530 it->second.started_screencasts.insert( 531 std::make_pair(ssrc, StartedCapture(capturer, format))); 532 533 // TODO(pthatcher): Verify we aren't re-using an existing id or 534 // ssrc. 535 StreamParams stream; 536 stream.id = streamid; 537 stream.ssrcs.push_back(ssrc); 538 VideoContentDescription* video = CreateVideoStreamUpdate(stream); 539 540 // TODO(pthatcher): Wait until view request before sending video. 541 video_channel->SetLocalContent(video, CA_UPDATE, NULL); 542 SendVideoStreamUpdate(session, video); 543 return true; 544 } 545 546 bool Call::StopScreencast(Session* session, 547 const std::string& streamid, uint32 ssrc) { 548 if (!StopScreencastWithoutSendingUpdate(session, ssrc)) { 549 return false; 550 } 551 552 VideoChannel *video_channel = GetVideoChannel(session); 553 if (!video_channel) { 554 LOG(LS_WARNING) << "Cannot add screencast" 555 << " because there is no video channel."; 556 return false; 557 } 558 559 StreamParams stream; 560 stream.id = streamid; 561 // No ssrcs 562 VideoContentDescription* video = CreateVideoStreamUpdate(stream); 563 564 video_channel->SetLocalContent(video, CA_UPDATE, NULL); 565 SendVideoStreamUpdate(session, video); 566 return true; 567 } 568 569 bool Call::StopScreencastWithoutSendingUpdate( 570 Session* session, uint32 ssrc) { 571 MediaSessionMap::iterator it = media_session_map_.find(session->id()); 572 if (it == media_session_map_.end()) { 573 return false; 574 } 575 576 VideoChannel *video_channel = GetVideoChannel(session); 577 if (!video_channel) { 578 LOG(LS_WARNING) << "Cannot remove screencast" 579 << " because there is no video channel."; 580 return false; 581 } 582 583 StartedScreencastMap::const_iterator screencast_iter = 584 it->second.started_screencasts.find(ssrc); 585 if (screencast_iter == it->second.started_screencasts.end()) { 586 LOG(LS_WARNING) << "Could not stop screencast " << ssrc 587 << " because there is no capturer."; 588 return false; 589 } 590 591 VideoCapturer* capturer = screencast_iter->second.capturer; 592 VideoFormat format = screencast_iter->second.format; 593 video_channel->SetCapturer(ssrc, NULL); 594 if (!session_client_->channel_manager()->StopVideoCapture( 595 capturer, format)) { 596 LOG(LS_WARNING) << "Could not stop screencast " << ssrc 597 << " because could not stop capture."; 598 return false; 599 } 600 video_channel->RemoveScreencast(ssrc); 601 it->second.started_screencasts.erase(ssrc); 602 return true; 603 } 604 605 VideoContentDescription* Call::CreateVideoStreamUpdate( 606 const StreamParams& stream) { 607 VideoContentDescription* video = new VideoContentDescription(); 608 video->set_multistream(true); 609 video->set_partial(true); 610 video->AddStream(stream); 611 return video; 612 } 613 614 void Call::SendVideoStreamUpdate( 615 Session* session, VideoContentDescription* video) { 616 // Takes the ownership of |video|. 617 rtc::scoped_ptr<VideoContentDescription> description(video); 618 const ContentInfo* video_info = 619 GetFirstVideoContent(session->local_description()); 620 if (video_info == NULL) { 621 LOG(LS_WARNING) << "Cannot send stream update for video."; 622 return; 623 } 624 625 std::vector<ContentInfo> contents; 626 contents.push_back( 627 ContentInfo(video_info->name, video_info->type, description.get())); 628 629 session->SendDescriptionInfoMessage(contents); 630 } 631 632 void Call::ContinuePlayDTMF() { 633 playing_dtmf_ = false; 634 635 // Check to see if we have a queued tone 636 if (queued_dtmf_.size() > 0) { 637 playing_dtmf_ = true; 638 639 int tone = queued_dtmf_.front(); 640 queued_dtmf_.pop_front(); 641 642 LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")"; 643 for (MediaSessionMap::iterator it = media_session_map_.begin(); 644 it != media_session_map_.end(); ++it) { 645 if (it->second.voice_channel != NULL) { 646 it->second.voice_channel->PressDTMF(tone, true); 647 } 648 } 649 650 // Post a message to play the next tone or at least clear the playing_dtmf_ 651 // bit. 652 rtc::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF); 653 } 654 } 655 656 void Call::Join(Call* call, bool enable) { 657 for (MediaSessionMap::iterator it = call->media_session_map_.begin(); 658 it != call->media_session_map_.end(); ++it) { 659 // Shouldn't already exist. 660 ASSERT(media_session_map_.find(it->first) == media_session_map_.end()); 661 media_session_map_[it->first] = it->second; 662 663 it->second.session->SignalState.connect(this, &Call::OnSessionState); 664 it->second.session->SignalError.connect(this, &Call::OnSessionError); 665 it->second.session->SignalReceivedTerminateReason 666 .connect(this, &Call::OnReceivedTerminateReason); 667 668 EnableSessionChannels(it->second.session, enable); 669 } 670 671 // Moved all the sessions over, so the other call should no longer have any. 672 call->media_session_map_.clear(); 673 } 674 675 void Call::StartConnectionMonitor(Session* session, int cms) { 676 VoiceChannel* voice_channel = GetVoiceChannel(session); 677 if (voice_channel) { 678 voice_channel->SignalConnectionMonitor.connect(this, 679 &Call::OnConnectionMonitor); 680 voice_channel->StartConnectionMonitor(cms); 681 } 682 683 VideoChannel* video_channel = GetVideoChannel(session); 684 if (video_channel) { 685 video_channel->SignalConnectionMonitor.connect(this, 686 &Call::OnConnectionMonitor); 687 video_channel->StartConnectionMonitor(cms); 688 } 689 } 690 691 void Call::StopConnectionMonitor(Session* session) { 692 VoiceChannel* voice_channel = GetVoiceChannel(session); 693 if (voice_channel) { 694 voice_channel->StopConnectionMonitor(); 695 voice_channel->SignalConnectionMonitor.disconnect(this); 696 } 697 698 VideoChannel* video_channel = GetVideoChannel(session); 699 if (video_channel) { 700 video_channel->StopConnectionMonitor(); 701 video_channel->SignalConnectionMonitor.disconnect(this); 702 } 703 } 704 705 void Call::StartAudioMonitor(Session* session, int cms) { 706 VoiceChannel* voice_channel = GetVoiceChannel(session); 707 if (voice_channel) { 708 voice_channel->SignalAudioMonitor.connect(this, &Call::OnAudioMonitor); 709 voice_channel->StartAudioMonitor(cms); 710 } 711 } 712 713 void Call::StopAudioMonitor(Session* session) { 714 VoiceChannel* voice_channel = GetVoiceChannel(session); 715 if (voice_channel) { 716 voice_channel->StopAudioMonitor(); 717 voice_channel->SignalAudioMonitor.disconnect(this); 718 } 719 } 720 721 bool Call::IsAudioMonitorRunning(Session* session) { 722 VoiceChannel* voice_channel = GetVoiceChannel(session); 723 if (voice_channel) { 724 return voice_channel->IsAudioMonitorRunning(); 725 } else { 726 return false; 727 } 728 } 729 730 void Call::StartSpeakerMonitor(Session* session) { 731 if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) { 732 if (!IsAudioMonitorRunning(session)) { 733 StartAudioMonitor(session, kAudioMonitorPollPeriodMillis); 734 } 735 CurrentSpeakerMonitor* speaker_monitor = 736 new cricket::CurrentSpeakerMonitor( 737 audio_source_proxy_.get(), session); 738 speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor); 739 speaker_monitor->Start(); 740 speaker_monitor_map_[session->id()] = speaker_monitor; 741 } else { 742 LOG(LS_WARNING) << "Already started speaker monitor for session " 743 << session->id() << "."; 744 } 745 } 746 747 void Call::StopSpeakerMonitor(Session* session) { 748 if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) { 749 LOG(LS_WARNING) << "Speaker monitor for session " 750 << session->id() << " already stopped."; 751 } else { 752 CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()]; 753 monitor->Stop(); 754 speaker_monitor_map_.erase(session->id()); 755 delete monitor; 756 } 757 } 758 759 void Call::OnConnectionMonitor(VoiceChannel* channel, 760 const std::vector<ConnectionInfo> &infos) { 761 SignalConnectionMonitor(this, infos); 762 } 763 764 void Call::OnMediaMonitor(VoiceChannel* channel, const VoiceMediaInfo& info) { 765 last_voice_media_info_ = info; 766 SignalMediaMonitor(this, info); 767 } 768 769 void Call::OnAudioMonitor(VoiceChannel* channel, const AudioInfo& info) { 770 SignalAudioMonitor(this, info); 771 } 772 773 void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) { 774 Session* session = static_cast<Session*>(monitor->session()); 775 MediaStreams* recv_streams = GetMediaStreams(session); 776 if (recv_streams) { 777 StreamParams stream; 778 recv_streams->GetAudioStream(StreamSelector(ssrc), &stream); 779 SignalSpeakerMonitor(this, session, stream); 780 } 781 } 782 783 void Call::OnConnectionMonitor(VideoChannel* channel, 784 const std::vector<ConnectionInfo> &infos) { 785 SignalVideoConnectionMonitor(this, infos); 786 } 787 788 void Call::OnMediaMonitor(VideoChannel* channel, const VideoMediaInfo& info) { 789 SignalVideoMediaMonitor(this, info); 790 } 791 792 void Call::OnDataReceived(DataChannel* channel, 793 const ReceiveDataParams& params, 794 const rtc::Buffer& payload) { 795 SignalDataReceived(this, params, payload); 796 } 797 798 uint32 Call::id() { 799 return id_; 800 } 801 802 void Call::OnSessionState(BaseSession* base_session, BaseSession::State state) { 803 Session* session = static_cast<Session*>(base_session); 804 switch (state) { 805 case Session::STATE_RECEIVEDACCEPT: 806 UpdateRemoteMediaStreams(session, 807 session->remote_description()->contents(), false); 808 session_client_->session_manager()->signaling_thread()->Clear(this, 809 MSG_TERMINATECALL); 810 break; 811 case Session::STATE_RECEIVEDREJECT: 812 case Session::STATE_RECEIVEDTERMINATE: 813 session_client_->session_manager()->signaling_thread()->Clear(this, 814 MSG_TERMINATECALL); 815 break; 816 default: 817 break; 818 } 819 SignalSessionState(this, session, state); 820 } 821 822 void Call::OnSessionError(BaseSession* base_session, Session::Error error) { 823 session_client_->session_manager()->signaling_thread()->Clear(this, 824 MSG_TERMINATECALL); 825 SignalSessionError(this, static_cast<Session*>(base_session), error); 826 } 827 828 void Call::OnSessionInfoMessage(Session* session, 829 const buzz::XmlElement* action_elem) { 830 if (!IsJingleViewRequest(action_elem)) { 831 return; 832 } 833 834 ViewRequest view_request; 835 ParseError error; 836 if (!ParseJingleViewRequest(action_elem, &view_request, &error)) { 837 LOG(LS_WARNING) << "Failed to parse view request: " << error.text; 838 return; 839 } 840 841 VideoChannel* video_channel = GetVideoChannel(session); 842 if (video_channel == NULL) { 843 LOG(LS_WARNING) << "Ignore view request since we have no video channel."; 844 return; 845 } 846 847 if (!video_channel->ApplyViewRequest(view_request)) { 848 LOG(LS_WARNING) << "Failed to ApplyViewRequest."; 849 } 850 } 851 852 void Call::OnRemoteDescriptionUpdate(BaseSession* base_session, 853 const ContentInfos& updated_contents) { 854 Session* session = static_cast<Session*>(base_session); 855 856 const ContentInfo* audio_content = GetFirstAudioContent(updated_contents); 857 if (audio_content) { 858 const AudioContentDescription* audio_update = 859 static_cast<const AudioContentDescription*>(audio_content->description); 860 if (!audio_update->codecs().empty()) { 861 UpdateVoiceChannelRemoteContent(session, audio_update); 862 } 863 } 864 865 const ContentInfo* video_content = GetFirstVideoContent(updated_contents); 866 if (video_content) { 867 const VideoContentDescription* video_update = 868 static_cast<const VideoContentDescription*>(video_content->description); 869 if (!video_update->codecs().empty()) { 870 UpdateVideoChannelRemoteContent(session, video_update); 871 } 872 } 873 874 const ContentInfo* data_content = GetFirstDataContent(updated_contents); 875 if (data_content) { 876 const DataContentDescription* data_update = 877 static_cast<const DataContentDescription*>(data_content->description); 878 if (!data_update->codecs().empty()) { 879 UpdateDataChannelRemoteContent(session, data_update); 880 } 881 } 882 883 UpdateRemoteMediaStreams(session, updated_contents, true); 884 } 885 886 bool Call::UpdateVoiceChannelRemoteContent( 887 Session* session, const AudioContentDescription* audio) { 888 VoiceChannel* voice_channel = GetVoiceChannel(session); 889 if (!voice_channel->SetRemoteContent(audio, CA_UPDATE, NULL)) { 890 const std::string error_desc = 891 "Failure in audio SetRemoteContent with CA_UPDATE"; 892 LOG(LS_ERROR) << error_desc; 893 session->SetError(BaseSession::ERROR_CONTENT, error_desc); 894 return false; 895 } 896 return true; 897 } 898 899 bool Call::UpdateVideoChannelRemoteContent( 900 Session* session, const VideoContentDescription* video) { 901 VideoChannel* video_channel = GetVideoChannel(session); 902 if (!video_channel->SetRemoteContent(video, CA_UPDATE, NULL)) { 903 const std::string error_desc = 904 "Failure in video SetRemoteContent with CA_UPDATE"; 905 LOG(LS_ERROR) << error_desc; 906 session->SetError(BaseSession::ERROR_CONTENT, error_desc); 907 return false; 908 } 909 return true; 910 } 911 912 bool Call::UpdateDataChannelRemoteContent( 913 Session* session, const DataContentDescription* data) { 914 DataChannel* data_channel = GetDataChannel(session); 915 if (!data_channel->SetRemoteContent(data, CA_UPDATE, NULL)) { 916 const std::string error_desc = 917 "Failure in data SetRemoteContent with CA_UPDATE"; 918 LOG(LS_ERROR) << error_desc; 919 session->SetError(BaseSession::ERROR_CONTENT, error_desc); 920 return false; 921 } 922 return true; 923 } 924 925 void Call::UpdateRemoteMediaStreams(Session* session, 926 const ContentInfos& updated_contents, 927 bool update_channels) { 928 MediaStreams* recv_streams = GetMediaStreams(session); 929 if (!recv_streams) 930 return; 931 932 cricket::MediaStreams added_streams; 933 cricket::MediaStreams removed_streams; 934 935 const ContentInfo* audio_content = GetFirstAudioContent(updated_contents); 936 if (audio_content) { 937 const AudioContentDescription* audio_update = 938 static_cast<const AudioContentDescription*>(audio_content->description); 939 UpdateRecvStreams(audio_update->streams(), 940 update_channels ? GetVoiceChannel(session) : NULL, 941 recv_streams->mutable_audio(), 942 added_streams.mutable_audio(), 943 removed_streams.mutable_audio()); 944 } 945 946 const ContentInfo* video_content = GetFirstVideoContent(updated_contents); 947 if (video_content) { 948 const VideoContentDescription* video_update = 949 static_cast<const VideoContentDescription*>(video_content->description); 950 UpdateRecvStreams(video_update->streams(), 951 update_channels ? GetVideoChannel(session) : NULL, 952 recv_streams->mutable_video(), 953 added_streams.mutable_video(), 954 removed_streams.mutable_video()); 955 } 956 957 const ContentInfo* data_content = GetFirstDataContent(updated_contents); 958 if (data_content) { 959 const DataContentDescription* data_update = 960 static_cast<const DataContentDescription*>(data_content->description); 961 UpdateRecvStreams(data_update->streams(), 962 update_channels ? GetDataChannel(session) : NULL, 963 recv_streams->mutable_data(), 964 added_streams.mutable_data(), 965 removed_streams.mutable_data()); 966 } 967 968 if (!added_streams.empty() || !removed_streams.empty()) { 969 SignalMediaStreamsUpdate(this, session, added_streams, removed_streams); 970 } 971 } 972 973 void FindStreamChanges(const std::vector<StreamParams>& streams, 974 const std::vector<StreamParams>& updates, 975 std::vector<StreamParams>* added_streams, 976 std::vector<StreamParams>* removed_streams) { 977 for (std::vector<StreamParams>::const_iterator update = updates.begin(); 978 update != updates.end(); ++update) { 979 StreamParams stream; 980 if (GetStreamByIds(streams, update->groupid, update->id, &stream)) { 981 if (!update->has_ssrcs()) { 982 removed_streams->push_back(stream); 983 } 984 } else { 985 // There's a bug on reflector that will send <stream>s even 986 // though there is not ssrc (which means there isn't really a 987 // stream). To work around it, we simply ignore new <stream>s 988 // that don't have any ssrcs. 989 if (update->has_ssrcs()) { 990 added_streams->push_back(*update); 991 } 992 } 993 } 994 } 995 996 void Call::UpdateRecvStreams(const std::vector<StreamParams>& update_streams, 997 BaseChannel* channel, 998 std::vector<StreamParams>* recv_streams, 999 std::vector<StreamParams>* added_streams, 1000 std::vector<StreamParams>* removed_streams) { 1001 FindStreamChanges(*recv_streams, 1002 update_streams, added_streams, removed_streams); 1003 AddRecvStreams(*added_streams, 1004 channel, recv_streams); 1005 RemoveRecvStreams(*removed_streams, 1006 channel, recv_streams); 1007 } 1008 1009 void Call::AddRecvStreams(const std::vector<StreamParams>& added_streams, 1010 BaseChannel* channel, 1011 std::vector<StreamParams>* recv_streams) { 1012 std::vector<StreamParams>::const_iterator stream; 1013 for (stream = added_streams.begin(); 1014 stream != added_streams.end(); 1015 ++stream) { 1016 AddRecvStream(*stream, channel, recv_streams); 1017 } 1018 } 1019 1020 void Call::AddRecvStream(const StreamParams& stream, 1021 BaseChannel* channel, 1022 std::vector<StreamParams>* recv_streams) { 1023 if (channel && stream.has_ssrcs()) { 1024 channel->AddRecvStream(stream); 1025 } 1026 recv_streams->push_back(stream); 1027 } 1028 1029 void Call::RemoveRecvStreams(const std::vector<StreamParams>& removed_streams, 1030 BaseChannel* channel, 1031 std::vector<StreamParams>* recv_streams) { 1032 std::vector<StreamParams>::const_iterator stream; 1033 for (stream = removed_streams.begin(); 1034 stream != removed_streams.end(); 1035 ++stream) { 1036 RemoveRecvStream(*stream, channel, recv_streams); 1037 } 1038 } 1039 1040 void Call::RemoveRecvStream(const StreamParams& stream, 1041 BaseChannel* channel, 1042 std::vector<StreamParams>* recv_streams) { 1043 if (channel && stream.has_ssrcs()) { 1044 // TODO(pthatcher): Change RemoveRecvStream to take a stream argument. 1045 channel->RemoveRecvStream(stream.first_ssrc()); 1046 } 1047 RemoveStreamByIds(recv_streams, stream.groupid, stream.id); 1048 } 1049 1050 void Call::OnReceivedTerminateReason(Session* session, 1051 const std::string& reason) { 1052 session_client_->session_manager()->signaling_thread()->Clear(this, 1053 MSG_TERMINATECALL); 1054 SignalReceivedTerminateReason(this, session, reason); 1055 } 1056 1057 // TODO(mdodd): Get ride of this method since all Hangouts are using a secure 1058 // connection. 1059 bool Call::secure() const { 1060 if (session_client_->secure() == SEC_DISABLED) { 1061 return false; 1062 } 1063 1064 bool ret = true; 1065 int i = 0; 1066 1067 MediaSessionMap::const_iterator it; 1068 for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) { 1069 LOG_F(LS_VERBOSE) << "session[" << i 1070 << "], check local and remote descriptions"; 1071 i++; 1072 1073 if (!SessionDescriptionContainsCrypto( 1074 it->second.session->local_description()) || 1075 !SessionDescriptionContainsCrypto( 1076 it->second.session->remote_description())) { 1077 ret = false; 1078 break; 1079 } 1080 } 1081 1082 LOG_F(LS_VERBOSE) << "secure=" << ret; 1083 return ret; 1084 } 1085 1086 bool Call::SessionDescriptionContainsCrypto( 1087 const SessionDescription* sdesc) const { 1088 if (sdesc == NULL) { 1089 LOG_F(LS_VERBOSE) << "sessionDescription is NULL"; 1090 return false; 1091 } 1092 1093 return ContentContainsCrypto(sdesc->GetContentByName(CN_AUDIO)) && 1094 ContentContainsCrypto(sdesc->GetContentByName(CN_VIDEO)); 1095 } 1096 1097 Session* Call::InternalInitiateSession(const std::string& id, 1098 const buzz::Jid& to, 1099 const std::string& initiator_name, 1100 const CallOptions& options) { 1101 const SessionDescription* offer = session_client_->CreateOffer(options); 1102 1103 Session* session = session_client_->CreateSession(id, this); 1104 // Only override the initiator_name if it was manually supplied. Otherwise, 1105 // session_client_ will supply the local jid as initiator in CreateOffer. 1106 if (!initiator_name.empty()) { 1107 session->set_initiator_name(initiator_name); 1108 } 1109 1110 AddSession(session, offer); 1111 session->Initiate(to.Str(), offer); 1112 1113 // After this timeout, terminate the call because the callee isn't 1114 // answering 1115 session_client_->session_manager()->signaling_thread()->Clear(this, 1116 MSG_TERMINATECALL); 1117 session_client_->session_manager()->signaling_thread()->PostDelayed( 1118 send_to_voicemail_ ? kSendToVoicemailTimeout : kNoVoicemailTimeout, 1119 this, MSG_TERMINATECALL); 1120 return session; 1121 } 1122 1123 AudioSourceProxy* Call::GetAudioSourceProxy() { 1124 return audio_source_proxy_.get(); 1125 } 1126 1127 } // namespace cricket 1128