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

« back to all changes in this revision

Viewing changes to protocols/jabber/googletalk/libjingle/talk/app/webrtc/peerconnectionimpl.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 2011, 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/app/webrtc/peerconnectionimpl.h"
29
 
 
30
 
#include <vector>
31
 
 
32
 
#include "talk/app/webrtc/mediastreamhandler.h"
33
 
#include "talk/app/webrtc/streamcollectionimpl.h"
34
 
#include "talk/base/logging.h"
35
 
#include "talk/base/stringencode.h"
36
 
#include "talk/session/phone/channelmanager.h"
37
 
#include "talk/session/phone/webrtcvideocapturer.h"
38
 
 
39
 
namespace {
40
 
 
41
 
// The number of the tokens in the config string.
42
 
static const size_t kConfigTokens = 2;
43
 
// Only the STUN or TURN server address appears in the config string.
44
 
static const size_t kConfigAddress = 1;
45
 
// Both of the STUN or TURN server address and port appear in the config string.
46
 
static const size_t kConfigAddressAndPort = 2;
47
 
static const size_t kServiceCount = 5;
48
 
// The default stun port.
49
 
static const int kDefaultPort = 3478;
50
 
 
51
 
// NOTE: Must be in the same order as the ServiceType enum.
52
 
static const char* kValidServiceTypes[kServiceCount] = {
53
 
    "STUN", "STUNS", "TURN", "TURNS", "INVALID" };
54
 
 
55
 
enum ServiceType {
56
 
  STUN,     // Indicates a STUN server.
57
 
  STUNS,    // Indicates a STUN server used with a TLS session.
58
 
  TURN,     // Indicates a TURN server
59
 
  TURNS,    // Indicates a TURN server used with a TLS session.
60
 
  INVALID,  // Unknown.
61
 
};
62
 
 
63
 
enum {
64
 
  MSG_ADDSTREAM = 1,
65
 
  MSG_REMOVESTREAM = 2,
66
 
  MSG_COMMITSTREAMCHANGES = 3,
67
 
  MSG_PROCESSSIGNALINGMESSAGE = 4,
68
 
  MSG_RETURNLOCALMEDIASTREAMS = 5,
69
 
  MSG_RETURNREMOTEMEDIASTREAMS = 6,
70
 
  MSG_CLOSE = 7,
71
 
  MSG_READYSTATE = 8,
72
 
  MSG_SDPSTATE = 9,
73
 
  MSG_TERMINATE = 10,
74
 
  MSG_STARTICE = 11,
75
 
  MSG_CREATEOFFER = 12,
76
 
  MSG_CREATEANSWER = 13,
77
 
  MSG_SETLOCALDESCRIPTION = 14,
78
 
  MSG_SETREMOTEDESCRIPTION = 15,
79
 
  MSG_PROCESSICEMESSAGE = 16,
80
 
  MSG_GETLOCALDESCRIPTION = 17,
81
 
  MSG_GETREMOTEDESCRIPTION = 18,
82
 
};
83
 
 
84
 
typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration
85
 
    StunConfiguration;
86
 
typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration
87
 
    TurnConfiguration;
88
 
 
89
 
bool static ParseConfigString(const std::string& config,
90
 
                              std::vector<StunConfiguration>* stun_config,
91
 
                              std::vector<TurnConfiguration>* turn_config) {
92
 
  std::vector<std::string> tokens;
93
 
  talk_base::tokenize(config, ' ', &tokens);
94
 
 
95
 
  if (tokens.size() != kConfigTokens) {
96
 
    LOG(WARNING) << "Invalid config string";
97
 
    return false;
98
 
  }
99
 
 
100
 
  ServiceType service_type = INVALID;
101
 
 
102
 
  const std::string& type = tokens[0];
103
 
  for (size_t i = 0; i < kServiceCount; ++i) {
104
 
    if (type.compare(kValidServiceTypes[i]) == 0) {
105
 
      service_type = static_cast<ServiceType>(i);
106
 
      break;
107
 
    }
108
 
  }
109
 
 
110
 
  if (service_type == INVALID) {
111
 
    LOG(WARNING) << "Invalid service type: " << type;
112
 
    return false;
113
 
  }
114
 
  std::string service_address = tokens[1];
115
 
 
116
 
  std::string address;
117
 
  int port;
118
 
  tokens.clear();
119
 
  talk_base::tokenize(service_address, ':', &tokens);
120
 
  if (tokens.size() != kConfigAddress &&
121
 
      tokens.size() != kConfigAddressAndPort) {
122
 
    LOG(WARNING) << "Invalid server address and port: " << service_address;
123
 
    return false;
124
 
  }
125
 
 
126
 
  if (tokens.size() == kConfigAddress) {
127
 
    address = tokens[0];
128
 
    port = kDefaultPort;
129
 
  } else {
130
 
    address = tokens[0];
131
 
    port = talk_base::FromString<int>(tokens[1]);
132
 
    if (port <= 0 || port > 0xffff) {
133
 
      LOG(WARNING) << "Invalid port: " << tokens[1];
134
 
      return false;
135
 
    }
136
 
  }
137
 
 
138
 
  // TODO: Currently the specification does not tell us how to parse
139
 
  // multiple addresses, username and password from the configuration string.
140
 
  switch (service_type) {
141
 
    case STUN:
142
 
      stun_config->push_back(StunConfiguration(address, port));
143
 
      break;
144
 
    case TURN:
145
 
      turn_config->push_back(TurnConfiguration(address, port, "", ""));
146
 
      break;
147
 
    case TURNS:
148
 
    case STUNS:
149
 
    case INVALID:
150
 
    default:
151
 
      LOG(WARNING) << "Configuration not supported";
152
 
      return false;
153
 
  }
154
 
  return true;
155
 
}
156
 
 
157
 
typedef talk_base::TypedMessageData<webrtc::LocalMediaStreamInterface*>
158
 
    LocalMediaStreamParams;
159
 
 
160
 
typedef talk_base::TypedMessageData<std::string> RoapSignalingParams;
161
 
 
162
 
struct IceOptionsParams : public talk_base::MessageData {
163
 
  explicit IceOptionsParams(webrtc::JsepInterface::IceOptions options)
164
 
      : options(options),
165
 
        result(false) {
166
 
  }
167
 
  webrtc::JsepInterface::IceOptions options;
168
 
  bool result;
169
 
};
170
 
 
171
 
struct JsepSessionDescriptionParams : public talk_base::MessageData {
172
 
  JsepSessionDescriptionParams()
173
 
      : result(false),
174
 
        desc(NULL),
175
 
        const_desc(NULL) {}
176
 
  bool result;
177
 
  webrtc::MediaHints hints;
178
 
  webrtc::JsepInterface::Action action;
179
 
  webrtc::SessionDescriptionInterface* desc;
180
 
  const webrtc::SessionDescriptionInterface* const_desc;
181
 
};
182
 
 
183
 
struct JsepIceCandidateParams : public talk_base::MessageData {
184
 
  explicit JsepIceCandidateParams(
185
 
      const webrtc::IceCandidateInterface* candidate)
186
 
      : result(false),
187
 
        candidate(candidate) {}
188
 
  bool result;
189
 
  const webrtc::IceCandidateInterface* candidate;
190
 
};
191
 
 
192
 
struct StreamCollectionParams : public talk_base::MessageData {
193
 
  explicit StreamCollectionParams(webrtc::StreamCollectionInterface* streams)
194
 
      : streams(streams) {}
195
 
  talk_base::scoped_refptr<webrtc::StreamCollectionInterface> streams;
196
 
};
197
 
 
198
 
struct MediaStreamParams : public talk_base::MessageData {
199
 
  explicit MediaStreamParams(webrtc::MediaStreamInterface* stream)
200
 
      : stream(stream) {}
201
 
  talk_base::scoped_refptr<webrtc::MediaStreamInterface> stream;
202
 
};
203
 
 
204
 
struct ReadyStateMessage : public talk_base::MessageData {
205
 
  ReadyStateMessage() : state(webrtc::PeerConnectionInterface::kNew) {}
206
 
  webrtc::PeerConnectionInterface::ReadyState state;
207
 
};
208
 
 
209
 
struct SdpStateMessage : public talk_base::MessageData {
210
 
  SdpStateMessage() : state(webrtc::PeerConnectionInterface::kSdpNew) {}
211
 
  webrtc::PeerConnectionInterface::SdpState state;
212
 
};
213
 
 
214
 
}  // namespace
215
 
 
216
 
namespace webrtc {
217
 
 
218
 
cricket::VideoCapturer* CreateVideoCapturer(VideoCaptureModule* vcm) {
219
 
  cricket::WebRtcVideoCapturer* video_capturer =
220
 
      new cricket::WebRtcVideoCapturer;
221
 
  if (!video_capturer->Init(vcm)) {
222
 
    delete video_capturer;
223
 
    video_capturer = NULL;
224
 
  }
225
 
  return video_capturer;
226
 
}
227
 
 
228
 
PeerConnection::PeerConnection(PeerConnectionFactory* factory)
229
 
    : factory_(factory),
230
 
      observer_(NULL),
231
 
      ready_state_(kNew),
232
 
      sdp_state_(kSdpNew),
233
 
      local_media_streams_(StreamCollection::Create()) {
234
 
}
235
 
 
236
 
PeerConnection::~PeerConnection() {
237
 
  signaling_thread()->Clear(this);
238
 
  signaling_thread()->Send(this, MSG_TERMINATE);
239
 
}
240
 
 
241
 
// Clean up what needs to be cleaned up on the signaling thread.
242
 
void PeerConnection::Terminate_s() {
243
 
  stream_handler_.reset();
244
 
  roap_signaling_.reset();
245
 
  mediastream_signaling_.reset();
246
 
  session_.reset();
247
 
  port_allocator_.reset();
248
 
}
249
 
 
250
 
bool PeerConnection::Initialize(bool use_roap,
251
 
                                const std::string& configuration,
252
 
                                PeerConnectionObserver* observer) {
253
 
  ASSERT(observer != NULL);
254
 
  if (!observer)
255
 
    return false;
256
 
  observer_ = observer;
257
 
  std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_config;
258
 
  std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_config;
259
 
 
260
 
  ParseConfigString(configuration, &stun_config, &turn_config);
261
 
 
262
 
  port_allocator_.reset(factory_->port_allocator_factory()->CreatePortAllocator(
263
 
      stun_config, turn_config));
264
 
 
265
 
  mediastream_signaling_.reset(new MediaStreamSignaling(
266
 
      factory_->signaling_thread(), this));
267
 
 
268
 
  session_.reset(new WebRtcSession(factory_->channel_manager(),
269
 
                                   factory_->signaling_thread(),
270
 
                                   factory_->worker_thread(),
271
 
                                   port_allocator_.get(),
272
 
                                   mediastream_signaling_.get()));
273
 
  stream_handler_.reset(new MediaStreamHandlers(session_.get()));
274
 
 
275
 
  // Initialize the WebRtcSession. It creates transport channels etc.
276
 
  if (!session_->Initialize())
277
 
    return false;
278
 
 
279
 
  if (use_roap) {
280
 
    roap_signaling_.reset(new RoapSignaling(
281
 
        mediastream_signaling_.get(),
282
 
        session_.get()));
283
 
    // Register Roap as receiver of local ice candidates.
284
 
    session_->RegisterObserver(roap_signaling_.get());
285
 
    roap_signaling_->SignalNewPeerConnectionMessage.connect(
286
 
        this, &PeerConnection::OnNewPeerConnectionMessage);
287
 
    roap_signaling_->SignalStateChange.connect(
288
 
        this, &PeerConnection::OnSignalingStateChange);
289
 
    ChangeReadyState(PeerConnectionInterface::kNegotiating);
290
 
  } else {
291
 
    // Register PeerConnection observer as receiver of local ice candidates.
292
 
    session_->RegisterObserver(observer_);
293
 
    session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange);
294
 
  }
295
 
  return true;
296
 
}
297
 
 
298
 
talk_base::scoped_refptr<StreamCollectionInterface>
299
 
PeerConnection::local_streams() {
300
 
  StreamCollectionParams msg(NULL);
301
 
  signaling_thread()->Send(this, MSG_RETURNLOCALMEDIASTREAMS, &msg);
302
 
  return msg.streams;
303
 
}
304
 
 
305
 
talk_base::scoped_refptr<StreamCollectionInterface>
306
 
PeerConnection::remote_streams() {
307
 
  StreamCollectionParams msg(NULL);
308
 
  signaling_thread()->Send(this, MSG_RETURNREMOTEMEDIASTREAMS, &msg);
309
 
  return msg.streams;
310
 
}
311
 
 
312
 
void PeerConnection::ProcessSignalingMessage(const std::string& msg) {
313
 
  RoapSignalingParams parameter(msg);
314
 
  signaling_thread()->Send(this, MSG_PROCESSSIGNALINGMESSAGE, &parameter);
315
 
}
316
 
 
317
 
void PeerConnection::AddStream(LocalMediaStreamInterface* local_stream) {
318
 
  LocalMediaStreamParams msg(local_stream);
319
 
  signaling_thread()->Send(this, MSG_ADDSTREAM, &msg);
320
 
}
321
 
 
322
 
void PeerConnection::RemoveStream(LocalMediaStreamInterface* remove_stream) {
323
 
  LocalMediaStreamParams msg(remove_stream);
324
 
  signaling_thread()->Send(this, MSG_REMOVESTREAM, &msg);
325
 
}
326
 
 
327
 
void PeerConnection::CommitStreamChanges() {
328
 
  signaling_thread()->Send(this, MSG_COMMITSTREAMCHANGES);
329
 
}
330
 
 
331
 
void PeerConnection::Close() {
332
 
  signaling_thread()->Send(this, MSG_CLOSE);
333
 
}
334
 
 
335
 
PeerConnectionInterface::ReadyState PeerConnection::ready_state() {
336
 
  ReadyStateMessage msg;
337
 
  signaling_thread()->Send(this, MSG_READYSTATE, &msg);
338
 
  return msg.state;
339
 
}
340
 
 
341
 
PeerConnectionInterface::SdpState PeerConnection::sdp_state() {
342
 
  SdpStateMessage msg;
343
 
  signaling_thread()->Send(this, MSG_SDPSTATE, &msg);
344
 
  return msg.state;
345
 
}
346
 
 
347
 
bool PeerConnection::StartIce(IceOptions options) {
348
 
  IceOptionsParams msg(options);
349
 
  signaling_thread()->Send(this, MSG_STARTICE, &msg);
350
 
  return msg.result;
351
 
}
352
 
 
353
 
SessionDescriptionInterface* PeerConnection::CreateOffer(
354
 
    const MediaHints& hints) {
355
 
  JsepSessionDescriptionParams msg;
356
 
  msg.hints = hints;
357
 
  signaling_thread()->Send(this, MSG_CREATEOFFER, &msg);
358
 
  return msg.desc;
359
 
}
360
 
 
361
 
SessionDescriptionInterface* PeerConnection::CreateAnswer(
362
 
    const MediaHints& hints,
363
 
    const SessionDescriptionInterface* offer) {
364
 
  JsepSessionDescriptionParams msg;
365
 
  msg.hints = hints;
366
 
  msg.const_desc = offer;
367
 
  signaling_thread()->Send(this, MSG_CREATEANSWER, &msg);
368
 
  return msg.desc;
369
 
}
370
 
 
371
 
bool PeerConnection::SetLocalDescription(Action action,
372
 
                                         SessionDescriptionInterface* desc) {
373
 
  JsepSessionDescriptionParams msg;
374
 
  msg.action = action;
375
 
  msg.desc = desc;
376
 
  signaling_thread()->Send(this, MSG_SETLOCALDESCRIPTION, &msg);
377
 
  return msg.result;
378
 
}
379
 
 
380
 
bool PeerConnection::SetRemoteDescription(Action action,
381
 
                                          SessionDescriptionInterface* desc) {
382
 
  JsepSessionDescriptionParams msg;
383
 
  msg.action = action;
384
 
  msg.desc = desc;
385
 
  signaling_thread()->Send(this, MSG_SETREMOTEDESCRIPTION, &msg);
386
 
  return msg.result;
387
 
}
388
 
 
389
 
bool PeerConnection::ProcessIceMessage(
390
 
    const IceCandidateInterface* ice_candidate) {
391
 
  JsepIceCandidateParams msg(ice_candidate);
392
 
  signaling_thread()->Send(this, MSG_PROCESSICEMESSAGE, &msg);
393
 
  return msg.result;
394
 
}
395
 
 
396
 
const SessionDescriptionInterface* PeerConnection::local_description() const {
397
 
  JsepSessionDescriptionParams msg;
398
 
  signaling_thread()->Send(const_cast<PeerConnection*>(this),
399
 
                           MSG_GETLOCALDESCRIPTION, &msg);
400
 
  return msg.const_desc;
401
 
}
402
 
 
403
 
const SessionDescriptionInterface* PeerConnection::remote_description() const {
404
 
  JsepSessionDescriptionParams msg;
405
 
  signaling_thread()->Send(const_cast<PeerConnection*>(this),
406
 
                           MSG_GETREMOTEDESCRIPTION, &msg);
407
 
  return msg.const_desc;
408
 
}
409
 
 
410
 
void PeerConnection::OnMessage(talk_base::Message* msg) {
411
 
  talk_base::MessageData* data = msg->pdata;
412
 
  switch (msg->message_id) {
413
 
    case MSG_ADDSTREAM: {
414
 
      LocalMediaStreamParams* msg(static_cast<LocalMediaStreamParams*> (data));
415
 
      local_media_streams_->AddStream(msg->data());
416
 
      break;
417
 
    }
418
 
    case MSG_REMOVESTREAM: {
419
 
      LocalMediaStreamParams* msg(static_cast<LocalMediaStreamParams*> (data));
420
 
      local_media_streams_->RemoveStream(msg->data());
421
 
      break;
422
 
    }
423
 
    case MSG_COMMITSTREAMCHANGES: {
424
 
      if (ready_state_ != PeerConnectionInterface::kClosed ||
425
 
          ready_state_ != PeerConnectionInterface::kClosing) {
426
 
        mediastream_signaling_->SetLocalStreams(local_media_streams_);
427
 
        // If we use ROAP an offer is created and we setup the local
428
 
        // media streams.
429
 
        if (roap_signaling_.get() != NULL) {
430
 
          roap_signaling_->CreateOffer(local_media_streams_);
431
 
          stream_handler_->CommitLocalStreams(local_media_streams_);
432
 
        }
433
 
      }
434
 
      break;
435
 
    }
436
 
    case MSG_PROCESSSIGNALINGMESSAGE: {
437
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
438
 
          roap_signaling_.get() != NULL)  {
439
 
        RoapSignalingParams* params(static_cast<RoapSignalingParams*> (data));
440
 
        roap_signaling_->ProcessSignalingMessage(params->data(),
441
 
                                                 local_media_streams_);
442
 
      }
443
 
      break;
444
 
    }
445
 
    case MSG_RETURNLOCALMEDIASTREAMS: {
446
 
      StreamCollectionParams* param(
447
 
          static_cast<StreamCollectionParams*> (data));
448
 
      param->streams = StreamCollection::Create(local_media_streams_);
449
 
      break;
450
 
    }
451
 
    case MSG_RETURNREMOTEMEDIASTREAMS: {
452
 
      StreamCollectionParams* param(
453
 
          static_cast<StreamCollectionParams*> (data));
454
 
      param->streams = mediastream_signaling_->remote_streams();
455
 
      break;
456
 
    }
457
 
    case MSG_CLOSE: {
458
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
459
 
          roap_signaling_.get() != NULL)  {
460
 
        ChangeReadyState(PeerConnectionInterface::kClosing);
461
 
        roap_signaling_->SendShutDown();
462
 
      }
463
 
      break;
464
 
    }
465
 
    case MSG_READYSTATE: {
466
 
      ReadyStateMessage* msg(static_cast<ReadyStateMessage*> (data));
467
 
      msg->state = ready_state_;
468
 
      break;
469
 
    }
470
 
    case MSG_SDPSTATE: {
471
 
      SdpStateMessage* msg(static_cast<SdpStateMessage*> (data));
472
 
      msg->state = sdp_state_;
473
 
      break;
474
 
    }
475
 
    case MSG_STARTICE: {
476
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
477
 
          ready_state_ != PeerConnectionInterface::kClosing) {
478
 
        IceOptionsParams* param(
479
 
                    static_cast<IceOptionsParams*> (data));
480
 
        param->result = session_->StartIce(param->options);
481
 
      }
482
 
      break;
483
 
    }
484
 
    case MSG_CREATEOFFER: {
485
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
486
 
          ready_state_ != PeerConnectionInterface::kClosing) {
487
 
        JsepSessionDescriptionParams* param(
488
 
            static_cast<JsepSessionDescriptionParams*> (data));
489
 
        param->desc = session_->CreateOffer(param->hints);
490
 
      }
491
 
      break;
492
 
    }
493
 
    case MSG_CREATEANSWER: {
494
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
495
 
          ready_state_ != PeerConnectionInterface::kClosing) {
496
 
        JsepSessionDescriptionParams* param(
497
 
            static_cast<JsepSessionDescriptionParams*> (data));
498
 
        param->desc = session_->CreateAnswer(param->hints,
499
 
                                             param->const_desc);
500
 
      }
501
 
      break;
502
 
    }
503
 
    case MSG_SETLOCALDESCRIPTION: {
504
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
505
 
          ready_state_ != PeerConnectionInterface::kClosing) {
506
 
        JsepSessionDescriptionParams* param(
507
 
            static_cast<JsepSessionDescriptionParams*> (data));
508
 
        param->result  = session_->SetLocalDescription(param->action,
509
 
                                                       param->desc);
510
 
        stream_handler_->CommitLocalStreams(local_media_streams_);
511
 
      }
512
 
      break;
513
 
    }
514
 
    case MSG_SETREMOTEDESCRIPTION: {
515
 
      if (ready_state_ != PeerConnectionInterface::kClosed &&
516
 
          ready_state_ != PeerConnectionInterface::kClosing) {
517
 
        JsepSessionDescriptionParams* param(
518
 
            static_cast<JsepSessionDescriptionParams*> (data));
519
 
        param->result  = session_->SetRemoteDescription(param->action,
520
 
                                                        param->desc);
521
 
      }
522
 
      break;
523
 
    }
524
 
    case MSG_PROCESSICEMESSAGE: {
525
 
      if (ready_state_ != PeerConnectionInterface::kClosed ||
526
 
          ready_state_ != PeerConnectionInterface::kClosing) {
527
 
        JsepIceCandidateParams * param(
528
 
            static_cast<JsepIceCandidateParams*> (data));
529
 
        param->result  = session_->ProcessIceMessage(param->candidate);
530
 
      }
531
 
      break;
532
 
    }
533
 
    case MSG_GETLOCALDESCRIPTION: {
534
 
      JsepSessionDescriptionParams* param(
535
 
          static_cast<JsepSessionDescriptionParams*> (data));
536
 
      param->const_desc  = session_->local_description();
537
 
      break;
538
 
    }
539
 
    case  MSG_GETREMOTEDESCRIPTION: {
540
 
      JsepSessionDescriptionParams* param(
541
 
          static_cast<JsepSessionDescriptionParams*> (data));
542
 
      param->const_desc  = session_->remote_description();
543
 
      break;
544
 
    }
545
 
    case MSG_TERMINATE: {
546
 
      Terminate_s();
547
 
      break;
548
 
    }
549
 
    default:
550
 
      ASSERT(!"NOT IMPLEMENTED");
551
 
      break;
552
 
  }
553
 
}
554
 
 
555
 
void PeerConnection::OnNewPeerConnectionMessage(const std::string& message) {
556
 
  observer_->OnSignalingMessage(message);
557
 
}
558
 
 
559
 
void PeerConnection::OnSignalingStateChange(
560
 
    RoapSignaling::State state) {
561
 
  switch (state) {
562
 
    case RoapSignaling::kInitializing:
563
 
      break;
564
 
    case RoapSignaling::kIdle:
565
 
      if (ready_state_ == PeerConnectionInterface::kNegotiating)
566
 
        ChangeReadyState(PeerConnectionInterface::kActive);
567
 
      ChangeSdpState(PeerConnectionInterface::kSdpIdle);
568
 
      break;
569
 
    case RoapSignaling::kWaitingForAnswer:
570
 
      ChangeSdpState(PeerConnectionInterface::kSdpWaiting);
571
 
      break;
572
 
    case RoapSignaling::kWaitingForOK:
573
 
      ChangeSdpState(PeerConnectionInterface::kSdpWaiting);
574
 
      break;
575
 
    case RoapSignaling::kShutingDown:
576
 
      ChangeReadyState(PeerConnectionInterface::kClosing);
577
 
      break;
578
 
    case RoapSignaling::kShutdownComplete:
579
 
      ChangeReadyState(PeerConnectionInterface::kClosed);
580
 
      signaling_thread()->Post(this, MSG_TERMINATE);
581
 
      break;
582
 
    default:
583
 
      ASSERT(!"NOT IMPLEMENTED");
584
 
      break;
585
 
  }
586
 
}
587
 
 
588
 
void PeerConnection::OnSessionStateChange(cricket::BaseSession* /*session*/,
589
 
                                          cricket::BaseSession::State state) {
590
 
  switch (state) {
591
 
    case cricket::BaseSession::STATE_INIT:
592
 
      ChangeReadyState(PeerConnectionInterface::kNew);
593
 
    case cricket::BaseSession::STATE_SENTINITIATE:
594
 
    case cricket::BaseSession::STATE_RECEIVEDINITIATE:
595
 
      ChangeReadyState(PeerConnectionInterface::kNegotiating);
596
 
      break;
597
 
    case cricket::BaseSession::STATE_SENTACCEPT:
598
 
    case cricket::BaseSession::STATE_RECEIVEDACCEPT:
599
 
      ChangeReadyState(PeerConnectionInterface::kActive);
600
 
      break;
601
 
    default:
602
 
      break;
603
 
  }
604
 
}
605
 
 
606
 
void PeerConnection::OnAddStream(MediaStreamInterface* stream) {
607
 
  stream_handler_->AddRemoteStream(stream);
608
 
  observer_->OnAddStream(stream);
609
 
}
610
 
 
611
 
void PeerConnection::OnRemoveStream(MediaStreamInterface* stream) {
612
 
  stream_handler_->RemoveRemoteStream(stream);
613
 
  observer_->OnRemoveStream(stream);
614
 
}
615
 
 
616
 
void PeerConnection::ChangeReadyState(
617
 
    PeerConnectionInterface::ReadyState ready_state) {
618
 
  ready_state_ = ready_state;
619
 
  observer_->OnStateChange(PeerConnectionObserver::kReadyState);
620
 
}
621
 
 
622
 
void PeerConnection::ChangeSdpState(
623
 
    PeerConnectionInterface::SdpState sdp_state) {
624
 
  sdp_state_ = sdp_state;
625
 
  observer_->OnStateChange(PeerConnectionObserver::kSdpState);
626
 
}
627
 
 
628
 
}  // namespace webrtc