~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/session/phone/call.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <string>
 
29
#include "talk/base/helpers.h"
 
30
#include "talk/base/logging.h"
 
31
#include "talk/base/thread.h"
 
32
#include "talk/p2p/base/parsing.h"
 
33
#include "talk/session/phone/call.h"
 
34
#include "talk/session/phone/mediasessionclient.h"
 
35
 
 
36
namespace cricket {
 
37
 
 
38
const uint32 MSG_CHECKAUTODESTROY = 1;
 
39
const uint32 MSG_TERMINATECALL = 2;
 
40
const uint32 MSG_PLAYDTMF = 3;
 
41
 
 
42
namespace {
 
43
const int kDTMFDelay = 300;  // msec
 
44
const size_t kMaxDTMFDigits = 30;
 
45
const int kSendToVoicemailTimeout = 1000*20;
 
46
const int kNoVoicemailTimeout = 1000*180;
 
47
const int kMediaMonitorInterval = 1000*15;
 
48
// In order to be the same as the server-side switching, this must be 100.
 
49
const int kAudioMonitorPollPeriodMillis = 100;
 
50
 
 
51
// V is a pointer type.
 
52
template<class K, class V>
 
53
V FindOrNull(const std::map<K, V>& map,
 
54
             const K& key) {
 
55
  typename std::map<K, V>::const_iterator it = map.find(key);
 
56
  return (it != map.end()) ? it->second : NULL;
 
57
}
 
58
 
 
59
}
 
60
 
 
61
Call::Call(MediaSessionClient* session_client)
 
62
    : id_(talk_base::CreateRandomId()),
 
63
      session_client_(session_client),
 
64
      local_renderer_(NULL),
 
65
      has_video_(false),
 
66
      has_data_(false),
 
67
      muted_(false),
 
68
      video_muted_(false),
 
69
      send_to_voicemail_(true),
 
70
      playing_dtmf_(false) {
 
71
}
 
72
 
 
73
Call::~Call() {
 
74
  while (sessions_.begin() != sessions_.end()) {
 
75
    Session* session = sessions_[0];
 
76
    RemoveSession(session);
 
77
    session_client_->session_manager()->DestroySession(session);
 
78
  }
 
79
  talk_base::Thread::Current()->Clear(this);
 
80
}
 
81
 
 
82
Session* Call::InitiateSession(const buzz::Jid &jid,
 
83
                               const CallOptions& options) {
 
84
  const SessionDescription* offer = session_client_->CreateOffer(options);
 
85
 
 
86
  Session* session = session_client_->CreateSession(this);
 
87
  AddSession(session, offer);
 
88
  session->Initiate(jid.Str(), offer);
 
89
 
 
90
  // After this timeout, terminate the call because the callee isn't
 
91
  // answering
 
92
  session_client_->session_manager()->signaling_thread()->Clear(this,
 
93
      MSG_TERMINATECALL);
 
94
  session_client_->session_manager()->signaling_thread()->PostDelayed(
 
95
    send_to_voicemail_ ? kSendToVoicemailTimeout : kNoVoicemailTimeout,
 
96
    this, MSG_TERMINATECALL);
 
97
  return session;
 
98
}
 
99
 
 
100
void Call::IncomingSession(
 
101
    Session* session, const SessionDescription* offer) {
 
102
  AddSession(session, offer);
 
103
 
 
104
  // Missed the first state, the initiate, which is needed by
 
105
  // call_client.
 
106
  SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE);
 
107
}
 
108
 
 
109
void Call::AcceptSession(Session* session,
 
110
                         const cricket::CallOptions& options) {
 
111
  std::vector<Session*>::iterator it;
 
112
  it = std::find(sessions_.begin(), sessions_.end(), session);
 
113
  ASSERT(it != sessions_.end());
 
114
  if (it != sessions_.end()) {
 
115
    session->Accept(
 
116
        session_client_->CreateAnswer(session->remote_description(), options));
 
117
  }
 
118
}
 
119
 
 
120
void Call::RejectSession(Session* session) {
 
121
  std::vector<Session*>::iterator it;
 
122
  it = std::find(sessions_.begin(), sessions_.end(), session);
 
123
  ASSERT(it != sessions_.end());
 
124
  // Assume polite decline.
 
125
  if (it != sessions_.end())
 
126
    session->Reject(STR_TERMINATE_DECLINE);
 
127
}
 
128
 
 
129
void Call::TerminateSession(Session* session) {
 
130
  ASSERT(std::find(sessions_.begin(), sessions_.end(), session)
 
131
         != sessions_.end());
 
132
  std::vector<Session*>::iterator it;
 
133
  it = std::find(sessions_.begin(), sessions_.end(), session);
 
134
  // Assume polite terminations.
 
135
  if (it != sessions_.end())
 
136
    (*it)->Terminate();
 
137
}
 
138
 
 
139
void Call::Terminate() {
 
140
  // Copy the list so that we can iterate over it in a stable way
 
141
  std::vector<Session*> sessions = sessions_;
 
142
 
 
143
  // There may be more than one session to terminate
 
144
  std::vector<Session*>::iterator it;
 
145
  for (it = sessions.begin(); it != sessions.end(); it++)
 
146
    TerminateSession(*it);
 
147
}
 
148
 
 
149
bool Call::SendViewRequest(Session* session,
 
150
                           const ViewRequest& view_request) {
 
151
  StaticVideoViews::const_iterator it;
 
152
  for (it = view_request.static_video_views.begin();
 
153
       it != view_request.static_video_views.end(); ++it) {
 
154
    StreamParams found_stream;
 
155
    bool found = recv_streams_.GetVideoStreamBySsrc(it->ssrc, &found_stream);
 
156
    if (!found) {
 
157
      LOG(LS_WARNING) <<
 
158
          "Tried sending view request for bad ssrc: " << it->ssrc;
 
159
      return false;
 
160
    }
 
161
  }
 
162
 
 
163
  XmlElements elems;
 
164
  WriteError error;
 
165
  if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) {
 
166
    LOG(LS_ERROR) << "Couldn't write out view request: " << error.text;
 
167
    return false;
 
168
  }
 
169
 
 
170
  return session->SendInfoMessage(elems);
 
171
}
 
172
 
 
173
void Call::SetLocalRenderer(VideoRenderer* renderer) {
 
174
  local_renderer_ = renderer;
 
175
  if (session_client_->GetFocus() == this) {
 
176
    session_client_->channel_manager()->SetLocalRenderer(renderer);
 
177
  }
 
178
}
 
179
 
 
180
void Call::SetVideoRenderer(Session* session, uint32 ssrc,
 
181
                            VideoRenderer* renderer) {
 
182
  VideoChannel* video_channel = GetVideoChannel(session);
 
183
  if (video_channel) {
 
184
    video_channel->SetRenderer(ssrc, renderer);
 
185
    LOG(LS_INFO) << "Set renderer of ssrc " << ssrc
 
186
                 << " to " << renderer << ".";
 
187
  } else {
 
188
    LOG(LS_INFO) << "Failed to set renderer of ssrc " << ssrc << ".";
 
189
  }
 
190
}
 
191
 
 
192
void Call::OnMessage(talk_base::Message* message) {
 
193
  switch (message->message_id) {
 
194
  case MSG_CHECKAUTODESTROY:
 
195
    // If no more sessions for this call, delete it
 
196
    if (sessions_.size() == 0)
 
197
      session_client_->DestroyCall(this);
 
198
    break;
 
199
  case MSG_TERMINATECALL:
 
200
    // Signal to the user that a timeout has happened and the call should
 
201
    // be sent to voicemail.
 
202
    if (send_to_voicemail_) {
 
203
      SignalSetupToCallVoicemail();
 
204
    }
 
205
 
 
206
    // Callee didn't answer - terminate call
 
207
    Terminate();
 
208
    break;
 
209
  case MSG_PLAYDTMF:
 
210
    ContinuePlayDTMF();
 
211
  }
 
212
}
 
213
 
 
214
const std::vector<Session*> &Call::sessions() {
 
215
  return sessions_;
 
216
}
 
217
 
 
218
bool Call::AddSession(Session* session, const SessionDescription* offer) {
 
219
  bool succeeded = true;
 
220
  VoiceChannel* voice_channel = NULL;
 
221
  VideoChannel* video_channel = NULL;
 
222
  DataChannel* data_channel = NULL;
 
223
 
 
224
  const ContentInfo* audio_offer = GetFirstAudioContent(offer);
 
225
  const ContentInfo* video_offer = GetFirstVideoContent(offer);
 
226
  const ContentInfo* data_offer = GetFirstDataContent(offer);
 
227
  has_video_ = (video_offer != NULL);
 
228
  has_data_ = (data_offer != NULL);
 
229
 
 
230
  ASSERT(audio_offer != NULL);
 
231
  // Create voice channel and start a media monitor.
 
232
  voice_channel = session_client_->channel_manager()->CreateVoiceChannel(
 
233
      session, audio_offer->name, has_video_);
 
234
  // voice_channel can be NULL in case of NullVoiceEngine.
 
235
  if (voice_channel) {
 
236
    voice_channel_map_[session->id()] = voice_channel;
 
237
    voice_channel->SignalMediaMonitor.connect(this, &Call::OnMediaMonitor);
 
238
    voice_channel->StartMediaMonitor(kMediaMonitorInterval);
 
239
  } else {
 
240
    succeeded = false;
 
241
  }
 
242
 
 
243
  // If desired, create video channel and start a media monitor.
 
244
  if (has_video_ && succeeded) {
 
245
    video_channel = session_client_->channel_manager()->CreateVideoChannel(
 
246
        session, video_offer->name, true, voice_channel);
 
247
    // video_channel can be NULL in case of NullVideoEngine.
 
248
    if (video_channel) {
 
249
      video_channel_map_[session->id()] = video_channel;
 
250
      video_channel->SignalMediaMonitor.connect(this, &Call::OnMediaMonitor);
 
251
      video_channel->StartMediaMonitor(kMediaMonitorInterval);
 
252
    } else {
 
253
      succeeded = false;
 
254
    }
 
255
  }
 
256
 
 
257
  // If desired, create data channel
 
258
  if (has_data_ && succeeded) {
 
259
    bool rtcp = false;
 
260
    data_channel = session_client_->channel_manager()->CreateDataChannel(
 
261
        session, data_offer->name, rtcp);
 
262
    if (data_channel) {
 
263
      data_channel_map_[session->id()] = data_channel;
 
264
      data_channel->SignalDataReceived.connect(this, &Call::OnDataReceived);
 
265
    } else {
 
266
      succeeded = false;
 
267
    }
 
268
  }
 
269
 
 
270
  if (succeeded) {
 
271
    // Add session to list, create channels for this session.
 
272
    sessions_.push_back(session);
 
273
    session->SignalState.connect(this, &Call::OnSessionState);
 
274
    session->SignalError.connect(this, &Call::OnSessionError);
 
275
    session->SignalInfoMessage.connect(
 
276
        this, &Call::OnSessionInfoMessage);
 
277
    session->SignalRemoteDescriptionUpdate.connect(
 
278
        this, &Call::OnRemoteDescriptionUpdate);
 
279
    session->SignalReceivedTerminateReason
 
280
      .connect(this, &Call::OnReceivedTerminateReason);
 
281
 
 
282
    // If this call has the focus, enable this channel.
 
283
    if (session_client_->GetFocus() == this) {
 
284
      voice_channel->Enable(true);
 
285
      if (video_channel) {
 
286
        video_channel->Enable(true);
 
287
      }
 
288
    }
 
289
 
 
290
    // Signal client.
 
291
    SignalAddSession(this, session);
 
292
  }
 
293
 
 
294
  return succeeded;
 
295
}
 
296
 
 
297
void Call::RemoveSession(Session* session) {
 
298
  // Remove session from list
 
299
  std::vector<Session*>::iterator it_session;
 
300
  it_session = std::find(sessions_.begin(), sessions_.end(), session);
 
301
  if (it_session == sessions_.end())
 
302
    return;
 
303
  sessions_.erase(it_session);
 
304
 
 
305
  // Destroy video channel
 
306
  std::map<std::string, VideoChannel*>::iterator it_vchannel;
 
307
  it_vchannel = video_channel_map_.find(session->id());
 
308
  if (it_vchannel != video_channel_map_.end()) {
 
309
    VideoChannel* video_channel = it_vchannel->second;
 
310
    video_channel_map_.erase(it_vchannel);
 
311
    session_client_->channel_manager()->DestroyVideoChannel(video_channel);
 
312
  }
 
313
 
 
314
  // Destroy voice channel
 
315
  std::map<std::string, VoiceChannel*>::iterator it_channel;
 
316
  it_channel = voice_channel_map_.find(session->id());
 
317
  if (it_channel != voice_channel_map_.end()) {
 
318
    VoiceChannel* voice_channel = it_channel->second;
 
319
    voice_channel_map_.erase(it_channel);
 
320
    session_client_->channel_manager()->DestroyVoiceChannel(voice_channel);
 
321
  }
 
322
 
 
323
  // Destroy data channel
 
324
  std::map<std::string, DataChannel*>::iterator it_dchannel;
 
325
  it_dchannel = data_channel_map_.find(session->id());
 
326
  if (it_dchannel != data_channel_map_.end()) {
 
327
    DataChannel* data_channel = it_dchannel->second;
 
328
    data_channel_map_.erase(it_dchannel);
 
329
    session_client_->channel_manager()->DestroyDataChannel(data_channel);
 
330
  }
 
331
 
 
332
  // Destroy speaker monitor
 
333
  StopSpeakerMonitor(session);
 
334
 
 
335
  // Signal client
 
336
  SignalRemoveSession(this, session);
 
337
 
 
338
  // The call auto destroys when the last session is removed
 
339
  talk_base::Thread::Current()->Post(this, MSG_CHECKAUTODESTROY);
 
340
}
 
341
 
 
342
VoiceChannel* Call::GetVoiceChannel(Session* session) {
 
343
  std::map<std::string, VoiceChannel*>::iterator it
 
344
    = voice_channel_map_.find(session->id());
 
345
  return (it != voice_channel_map_.end()) ? it->second : NULL;
 
346
}
 
347
 
 
348
VideoChannel* Call::GetVideoChannel(Session* session) {
 
349
  std::map<std::string, VideoChannel*>::iterator it
 
350
    = video_channel_map_.find(session->id());
 
351
  return (it != video_channel_map_.end()) ? it->second : NULL;
 
352
}
 
353
 
 
354
DataChannel* Call::GetDataChannel(Session* session) {
 
355
  std::map<std::string, DataChannel*>::iterator it =
 
356
      data_channel_map_.find(session->id());
 
357
  return (it != data_channel_map_.end()) ? it->second : NULL;
 
358
}
 
359
 
 
360
void Call::EnableChannels(bool enable) {
 
361
  std::vector<Session*>::iterator it;
 
362
  for (it = sessions_.begin(); it != sessions_.end(); it++) {
 
363
    VoiceChannel* voice_channel = GetVoiceChannel(*it);
 
364
    VideoChannel* video_channel = GetVideoChannel(*it);
 
365
    DataChannel* data_channel = GetDataChannel(*it);
 
366
    if (voice_channel != NULL)
 
367
      voice_channel->Enable(enable);
 
368
    if (video_channel != NULL)
 
369
      video_channel->Enable(enable);
 
370
    if (data_channel != NULL)
 
371
      data_channel->Enable(enable);
 
372
  }
 
373
  session_client_->channel_manager()->SetLocalRenderer(
 
374
      (enable) ? local_renderer_ : NULL);
 
375
}
 
376
 
 
377
void Call::Mute(bool mute) {
 
378
  muted_ = mute;
 
379
  std::vector<Session*>::iterator it;
 
380
  for (it = sessions_.begin(); it != sessions_.end(); it++) {
 
381
    VoiceChannel* voice_channel = voice_channel_map_[(*it)->id()];
 
382
    if (voice_channel != NULL)
 
383
      voice_channel->Mute(mute);
 
384
  }
 
385
}
 
386
 
 
387
void Call::MuteVideo(bool mute) {
 
388
  video_muted_ = mute;
 
389
  std::vector<Session*>::iterator it;
 
390
  for (it = sessions_.begin(); it != sessions_.end(); it++) {
 
391
    VideoChannel* video_channel = video_channel_map_[(*it)->id()];
 
392
    if (video_channel != NULL)
 
393
      video_channel->Mute(mute);
 
394
  }
 
395
}
 
396
 
 
397
void Call::SendData(Session* session,
 
398
                    const DataMediaChannel::SendDataParams& params,
 
399
                    const std::string& data) {
 
400
  DataChannel* data_channel = GetDataChannel(session);
 
401
  if (!data_channel) {
 
402
    LOG(LS_WARNING) << "Could not send data: no data channel.";
 
403
    return;
 
404
  }
 
405
 
 
406
  data_channel->SendData(params, data);
 
407
}
 
408
 
 
409
void Call::PressDTMF(int event) {
 
410
  // Queue up this digit
 
411
  if (queued_dtmf_.size() < kMaxDTMFDigits) {
 
412
    LOG(LS_INFO) << "Call::PressDTMF(" << event << ")";
 
413
 
 
414
    queued_dtmf_.push_back(event);
 
415
 
 
416
    if (!playing_dtmf_) {
 
417
      ContinuePlayDTMF();
 
418
    }
 
419
  }
 
420
}
 
421
 
 
422
void Call::ContinuePlayDTMF() {
 
423
  playing_dtmf_ = false;
 
424
 
 
425
  // Check to see if we have a queued tone
 
426
  if (queued_dtmf_.size() > 0) {
 
427
    playing_dtmf_ = true;
 
428
 
 
429
    int tone = queued_dtmf_.front();
 
430
    queued_dtmf_.pop_front();
 
431
 
 
432
    LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")";
 
433
    std::vector<Session*>::iterator it;
 
434
    for (it = sessions_.begin(); it != sessions_.end(); it++) {
 
435
      VoiceChannel* voice_channel = voice_channel_map_[(*it)->id()];
 
436
      if (voice_channel != NULL) {
 
437
        voice_channel->PressDTMF(tone, true);
 
438
      }
 
439
    }
 
440
 
 
441
    // Post a message to play the next tone or at least clear the playing_dtmf_
 
442
    // bit.
 
443
    talk_base::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF);
 
444
  }
 
445
}
 
446
 
 
447
void Call::Join(Call* call, bool enable) {
 
448
  while (call->sessions_.size() != 0) {
 
449
    // Move session
 
450
    Session* session = call->sessions_[0];
 
451
    call->sessions_.erase(call->sessions_.begin());
 
452
    sessions_.push_back(session);
 
453
    session->SignalState.connect(this, &Call::OnSessionState);
 
454
    session->SignalError.connect(this, &Call::OnSessionError);
 
455
    session->SignalReceivedTerminateReason
 
456
      .connect(this, &Call::OnReceivedTerminateReason);
 
457
 
 
458
    // Move voice channel
 
459
    std::map<std::string, VoiceChannel*>::iterator it_channel;
 
460
    it_channel = call->voice_channel_map_.find(session->id());
 
461
    if (it_channel != call->voice_channel_map_.end()) {
 
462
      VoiceChannel* voice_channel = (*it_channel).second;
 
463
      call->voice_channel_map_.erase(it_channel);
 
464
      voice_channel_map_[session->id()] = voice_channel;
 
465
      voice_channel->Enable(enable);
 
466
    }
 
467
 
 
468
    // Move video channel
 
469
    std::map<std::string, VideoChannel*>::iterator it_vchannel;
 
470
    it_vchannel = call->video_channel_map_.find(session->id());
 
471
    if (it_vchannel != call->video_channel_map_.end()) {
 
472
      VideoChannel* video_channel = (*it_vchannel).second;
 
473
      call->video_channel_map_.erase(it_vchannel);
 
474
      video_channel_map_[session->id()] = video_channel;
 
475
      video_channel->Enable(enable);
 
476
    }
 
477
 
 
478
    // TODO: Move data channel?
 
479
  }
 
480
}
 
481
 
 
482
void Call::StartConnectionMonitor(Session* session, int cms) {
 
483
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
484
  if (voice_channel) {
 
485
    voice_channel->SignalConnectionMonitor.connect(this,
 
486
        &Call::OnConnectionMonitor);
 
487
    voice_channel->StartConnectionMonitor(cms);
 
488
  }
 
489
 
 
490
  VideoChannel* video_channel = GetVideoChannel(session);
 
491
  if (video_channel) {
 
492
    video_channel->SignalConnectionMonitor.connect(this,
 
493
        &Call::OnConnectionMonitor);
 
494
    video_channel->StartConnectionMonitor(cms);
 
495
  }
 
496
}
 
497
 
 
498
void Call::StopConnectionMonitor(Session* session) {
 
499
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
500
  if (voice_channel) {
 
501
    voice_channel->StopConnectionMonitor();
 
502
    voice_channel->SignalConnectionMonitor.disconnect(this);
 
503
  }
 
504
 
 
505
  VideoChannel* video_channel = GetVideoChannel(session);
 
506
  if (video_channel) {
 
507
    video_channel->StopConnectionMonitor();
 
508
    video_channel->SignalConnectionMonitor.disconnect(this);
 
509
  }
 
510
}
 
511
 
 
512
void Call::StartAudioMonitor(Session* session, int cms) {
 
513
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
514
  if (voice_channel) {
 
515
    voice_channel->SignalAudioMonitor.connect(this, &Call::OnAudioMonitor);
 
516
    voice_channel->StartAudioMonitor(cms);
 
517
  }
 
518
}
 
519
 
 
520
void Call::StopAudioMonitor(Session* session) {
 
521
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
522
  if (voice_channel) {
 
523
    voice_channel->StopAudioMonitor();
 
524
    voice_channel->SignalAudioMonitor.disconnect(this);
 
525
  }
 
526
}
 
527
 
 
528
bool Call::IsAudioMonitorRunning(Session* session) {
 
529
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
530
  if (voice_channel) {
 
531
    return voice_channel->IsAudioMonitorRunning();
 
532
  } else {
 
533
    return false;
 
534
  }
 
535
}
 
536
 
 
537
void Call::StartSpeakerMonitor(Session* session) {
 
538
  if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
 
539
    if (!IsAudioMonitorRunning(session)) {
 
540
      StartAudioMonitor(session, kAudioMonitorPollPeriodMillis);
 
541
    }
 
542
    CurrentSpeakerMonitor* speaker_monitor =
 
543
        new cricket::CurrentSpeakerMonitor(this, session);
 
544
    speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor);
 
545
    speaker_monitor->Start();
 
546
    speaker_monitor_map_[session->id()] = speaker_monitor;
 
547
  } else {
 
548
    LOG(LS_WARNING) << "Already started speaker monitor for session "
 
549
                    << session->id() << ".";
 
550
  }
 
551
}
 
552
 
 
553
void Call::StopSpeakerMonitor(Session* session) {
 
554
  if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
 
555
    LOG(LS_WARNING) << "Speaker monitor for session "
 
556
                    << session->id() << " already stopped.";
 
557
  } else {
 
558
    CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()];
 
559
    monitor->Stop();
 
560
    speaker_monitor_map_.erase(session->id());
 
561
    delete monitor;
 
562
  }
 
563
}
 
564
 
 
565
void Call::OnConnectionMonitor(VoiceChannel* channel,
 
566
                               const std::vector<ConnectionInfo> &infos) {
 
567
  SignalConnectionMonitor(this, infos);
 
568
}
 
569
 
 
570
void Call::OnMediaMonitor(VoiceChannel* channel, const VoiceMediaInfo& info) {
 
571
  SignalMediaMonitor(this, info);
 
572
}
 
573
 
 
574
void Call::OnAudioMonitor(VoiceChannel* channel, const AudioInfo& info) {
 
575
  SignalAudioMonitor(this, info);
 
576
}
 
577
 
 
578
void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) {
 
579
  StreamParams stream;
 
580
  recv_streams_.GetAudioStreamBySsrc(ssrc, &stream);
 
581
  SignalSpeakerMonitor(this, static_cast<Session*>(monitor->session()),
 
582
                       stream);
 
583
}
 
584
 
 
585
void Call::OnConnectionMonitor(VideoChannel* channel,
 
586
                               const std::vector<ConnectionInfo> &infos) {
 
587
  SignalVideoConnectionMonitor(this, infos);
 
588
}
 
589
 
 
590
void Call::OnMediaMonitor(VideoChannel* channel, const VideoMediaInfo& info) {
 
591
  SignalVideoMediaMonitor(this, info);
 
592
}
 
593
 
 
594
void Call::OnDataReceived(DataChannel* channel,
 
595
                          const ReceiveDataParams& params,
 
596
                          const std::string& data) {
 
597
  SignalDataReceived(this, params, data);
 
598
}
 
599
 
 
600
uint32 Call::id() {
 
601
  return id_;
 
602
}
 
603
 
 
604
void Call::OnSessionState(BaseSession* session, BaseSession::State state) {
 
605
  switch (state) {
 
606
    case Session::STATE_RECEIVEDACCEPT:
 
607
    case Session::STATE_RECEIVEDREJECT:
 
608
    case Session::STATE_RECEIVEDTERMINATE:
 
609
      session_client_->session_manager()->signaling_thread()->Clear(this,
 
610
          MSG_TERMINATECALL);
 
611
      break;
 
612
    default:
 
613
      break;
 
614
  }
 
615
  SignalSessionState(this, static_cast<Session*>(session), state);
 
616
}
 
617
 
 
618
void Call::OnSessionError(BaseSession* session, Session::Error error) {
 
619
  session_client_->session_manager()->signaling_thread()->Clear(this,
 
620
      MSG_TERMINATECALL);
 
621
  SignalSessionError(this, static_cast<Session*>(session), error);
 
622
}
 
623
 
 
624
void Call::OnSessionInfoMessage(Session* session,
 
625
                                const buzz::XmlElement* action_elem) {
 
626
  if (!IsJingleViewRequest(action_elem)) {
 
627
    return;
 
628
  }
 
629
 
 
630
  ViewRequest view_request;
 
631
  ParseError error;
 
632
  if (!ParseJingleViewRequest(action_elem, &view_request, &error)) {
 
633
    LOG(LS_WARNING) << "Failed to parse view request: " << error.text;
 
634
    return;
 
635
  }
 
636
 
 
637
  VideoChannel* video_channel = GetVideoChannel(session);
 
638
  if (video_channel == NULL) {
 
639
    LOG(LS_WARNING) << "Ignore view request since we have no video channel.";
 
640
    return;
 
641
  }
 
642
 
 
643
  if (!video_channel->ApplyViewRequest(view_request)) {
 
644
    LOG(LS_WARNING) << "Failed to ApplyViewRequest.";
 
645
  }
 
646
}
 
647
 
 
648
void FindStreamChanges(const std::vector<StreamParams>& streams,
 
649
                       const std::vector<StreamParams>& updates,
 
650
                       std::vector<StreamParams>* added_streams,
 
651
                       std::vector<StreamParams>* removed_streams) {
 
652
  for (std::vector<StreamParams>::const_iterator update = updates.begin();
 
653
       update != updates.end(); ++update) {
 
654
    StreamParams stream;
 
655
    if (GetStreamByNickAndName(streams, update->nick, update->name, &stream)) {
 
656
      if (!update->has_ssrcs()) {
 
657
        removed_streams->push_back(stream);
 
658
      }
 
659
    } else {
 
660
      // There's a bug on reflector that will send <stream>s even
 
661
      // though there is not ssrc (which means there isn't really a
 
662
      // stream).  To work around it, we simply ignore new <stream>s
 
663
      // that don't have any ssrcs.
 
664
      if (update->has_ssrcs()) {
 
665
        added_streams->push_back(*update);
 
666
      }
 
667
    }
 
668
  }
 
669
}
 
670
 
 
671
void Call::UpdateRecvStreams(const std::vector<StreamParams>& update_streams,
 
672
                             BaseChannel* channel,
 
673
                             std::vector<StreamParams>* recv_streams,
 
674
                             std::vector<StreamParams>* added_streams,
 
675
                             std::vector<StreamParams>* removed_streams) {
 
676
  FindStreamChanges(*recv_streams,
 
677
                    update_streams, added_streams, removed_streams);
 
678
  AddRecvStreams(*added_streams,
 
679
                 channel, recv_streams);
 
680
  RemoveRecvStreams(*removed_streams,
 
681
                    channel, recv_streams);
 
682
}
 
683
 
 
684
void Call::AddRecvStreams(const std::vector<StreamParams>& added_streams,
 
685
                          BaseChannel* channel,
 
686
                          std::vector<StreamParams>* recv_streams) {
 
687
  std::vector<StreamParams>::const_iterator stream;
 
688
  for (stream = added_streams.begin();
 
689
       stream != added_streams.end();
 
690
       ++stream) {
 
691
    AddRecvStream(*stream, channel, recv_streams);
 
692
  }
 
693
}
 
694
 
 
695
void Call::AddRecvStream(const StreamParams& stream,
 
696
                         BaseChannel* channel,
 
697
                         std::vector<StreamParams>* recv_streams) {
 
698
  if (channel && stream.has_ssrcs()) {
 
699
    channel->AddRecvStream(stream);
 
700
  }
 
701
  recv_streams->push_back(stream);
 
702
}
 
703
 
 
704
void Call::RemoveRecvStreams(const std::vector<StreamParams>& removed_streams,
 
705
                             BaseChannel* channel,
 
706
                             std::vector<StreamParams>* recv_streams) {
 
707
  std::vector<StreamParams>::const_iterator stream;
 
708
  for (stream = removed_streams.begin();
 
709
       stream != removed_streams.end();
 
710
       ++stream) {
 
711
    RemoveRecvStream(*stream, channel, recv_streams);
 
712
  }
 
713
}
 
714
 
 
715
void Call::RemoveRecvStream(const StreamParams& stream,
 
716
                            BaseChannel* channel,
 
717
                            std::vector<StreamParams>* recv_streams) {
 
718
  if (channel && stream.has_ssrcs()) {
 
719
    // TODO: Change RemoveRecvStream to take a stream argument.
 
720
    channel->RemoveRecvStream(stream.first_ssrc());
 
721
  }
 
722
  RemoveStreamByNickAndName(recv_streams, stream.nick, stream.name);
 
723
}
 
724
 
 
725
void Call::OnRemoteDescriptionUpdate(BaseSession* base_session,
 
726
                                     const ContentInfos& updated_contents) {
 
727
  Session* session = static_cast<Session*>(base_session);
 
728
 
 
729
  cricket::MediaStreams added_streams;
 
730
  cricket::MediaStreams removed_streams;
 
731
  std::vector<StreamParams>::const_iterator stream;
 
732
 
 
733
  const ContentInfo* audio_content = GetFirstAudioContent(updated_contents);
 
734
  if (audio_content) {
 
735
    const AudioContentDescription* audio_update =
 
736
        static_cast<const AudioContentDescription*>(audio_content->description);
 
737
    if (!audio_update->codecs().empty()) {
 
738
      UpdateVoiceChannelRemoteContent(session, audio_update);
 
739
    }
 
740
    UpdateRecvStreams(audio_update->streams(),
 
741
                      GetVoiceChannel(session),
 
742
                      recv_streams_.mutable_audio(),
 
743
                      added_streams.mutable_audio(),
 
744
                      removed_streams.mutable_audio());
 
745
  }
 
746
 
 
747
  const ContentInfo* video_content = GetFirstVideoContent(updated_contents);
 
748
  if (video_content) {
 
749
    const VideoContentDescription* video_update =
 
750
        static_cast<const VideoContentDescription*>(video_content->description);
 
751
    if (!video_update->codecs().empty()) {
 
752
      UpdateVideoChannelRemoteContent(session, video_update);
 
753
    }
 
754
    UpdateRecvStreams(video_update->streams(),
 
755
                      GetVideoChannel(session),
 
756
                      recv_streams_.mutable_video(),
 
757
                      added_streams.mutable_video(),
 
758
                      removed_streams.mutable_video());
 
759
  }
 
760
 
 
761
  const ContentInfo* data_content = GetFirstDataContent(updated_contents);
 
762
  if (data_content) {
 
763
    const DataContentDescription* data_update =
 
764
        static_cast<const DataContentDescription*>(data_content->description);
 
765
    if (!data_update->codecs().empty()) {
 
766
      UpdateDataChannelRemoteContent(session, data_update);
 
767
    }
 
768
    UpdateRecvStreams(data_update->streams(),
 
769
                      GetDataChannel(session),
 
770
                      recv_streams_.mutable_data(),
 
771
                      added_streams.mutable_data(),
 
772
                      removed_streams.mutable_data());
 
773
  }
 
774
 
 
775
  if (!added_streams.empty() || !removed_streams.empty()) {
 
776
    SignalMediaStreamsUpdate(this, session, added_streams, removed_streams);
 
777
  }
 
778
}
 
779
 
 
780
bool Call::UpdateVoiceChannelRemoteContent(
 
781
    Session* session, const AudioContentDescription* audio) {
 
782
  VoiceChannel* voice_channel = GetVoiceChannel(session);
 
783
  if (!voice_channel->SetRemoteContent(audio, CA_UPDATE)) {
 
784
    LOG(LS_ERROR) << "Failure in audio SetRemoteContent with CA_UPDATE";
 
785
    session->SetError(BaseSession::ERROR_CONTENT);
 
786
    return false;
 
787
  }
 
788
  return true;
 
789
}
 
790
 
 
791
bool Call::UpdateVideoChannelRemoteContent(
 
792
    Session* session, const VideoContentDescription* video) {
 
793
  VideoChannel* video_channel = GetVideoChannel(session);
 
794
  if (!video_channel->SetRemoteContent(video, CA_UPDATE)) {
 
795
    LOG(LS_ERROR) << "Failure in video SetRemoteContent with CA_UPDATE";
 
796
    session->SetError(BaseSession::ERROR_CONTENT);
 
797
    return false;
 
798
  }
 
799
  return true;
 
800
}
 
801
 
 
802
bool Call::UpdateDataChannelRemoteContent(
 
803
    Session* session, const DataContentDescription* data) {
 
804
  DataChannel* data_channel = GetDataChannel(session);
 
805
  if (!data_channel->SetRemoteContent(data, CA_UPDATE)) {
 
806
    LOG(LS_ERROR) << "Failure in data SetRemoteContent with CA_UPDATE";
 
807
    session->SetError(BaseSession::ERROR_CONTENT);
 
808
    return false;
 
809
  }
 
810
  return true;
 
811
}
 
812
 
 
813
void Call::OnReceivedTerminateReason(Session* session,
 
814
                                     const std::string& reason) {
 
815
  session_client_->session_manager()->signaling_thread()->Clear(this,
 
816
    MSG_TERMINATECALL);
 
817
  SignalReceivedTerminateReason(this, session, reason);
 
818
}
 
819
 
 
820
}  // namespace cricket